#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef long double ld; typedef pair pii; typedef vector vi; typedef vector vs; typedef vector< vector > vvi; typedef vector vl; typedef vector< vector > vvl; #define forn(i, n) for (int i = 0; i < (int)(n); i++) #define forv(i, v) forn(i, v.size()) #define all(v) v.begin(), v.end() #define mp make_pair #define pb push_back #define lf(v) ((v << 1) + 1) #define rg(v) ((v + 1) << 1) struct Node { int add; int cnt[26]; bool f; }; const int MAXN = 100500; Node md[MAXN * 4]; void relax(int v, int l, int r) { if (!md[v].f) return; int cc[26]; memcpy(cc, md[v].cnt, sizeof(cc)); forn(c, 26) { md[v].cnt[(c + md[v].add) % 26] = cc[c]; } md[v].f = false; if (r - l > 1) { md[lf(v)].f = md[rg(v)].f = true; md[lf(v)].add = (md[lf(v)].add + md[v].add) % 26; md[rg(v)].add = (md[rg(v)].add + md[v].add) % 26; } md[v].add = 0; } void updateOne(int v) { forn(c, 26) { md[v].cnt[c] = md[lf(v)].cnt[c] + md[rg(v)].cnt[c]; } } void updateSegm(int v, int l, int r, int x, int y, int add) { relax(v, l, r); if (x == l && y == r) { md[v].f = true; md[v].add = add; relax(v, l, r); return; } int mid = (l + r) >> 1; if (x < mid) { updateSegm(lf(v), l, mid, x, min(y, mid), add); } if (y > mid) { updateSegm(rg(v), mid, r, max(x, mid), y, add); } relax(lf(v), l, mid); relax(rg(v), mid, r); updateOne(v); } vi rmq(int v, int l, int r, int x, int y) { relax(v, l, r); if (x == l && y == r) { vi ret(26); forn(c, 26) ret[c] = md[v].cnt[c]; return ret; } int mid = (l + r) >> 1; vi res(26); if (x < mid) { vi rl = rmq(lf(v), l, mid, x, min(y, mid)); forn(c, 26) { res[c] = rl[c]; } } if (y > mid) { vi rr = rmq(rg(v), mid, r, max(x, mid), y); forn(c, 26) { res[c] += rr[c]; } } return res; } vi a; void create(int v, int l, int r) { if (l >= r) return; md[v].f = false; md[v].add = 0; if (l + 1 == r) { md[v].cnt[a[l]] = 1; } else { int mid = (l + r) >> 1; create(lf(v), l, mid); create(rg(v), mid, r); updateOne(v); } } const ll MOD = 1000000007; vl p2; int calc(const vi& c) { int p = 0; forv(i, c) { if (c[i]) { p += c[i] - 1; } } ll ret = (p2[p] - 1 + MOD) % MOD; forv(i, c) { if (c[i] == 0) continue; int p = c[i] - 1; forv(j, c) { if (j != i && c[j]) { p += c[j] - 1; } } ret = (ret + p2[p]) % MOD; } return (int)ret; } int main() { #ifdef NEREVAR_PROJECT freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); #endif int n, q; scanf("%d %d\n", &n, &q); a = vi(n); string s; getline(cin, s); forv(i, s) { a[i] = s[i] - 'a'; } p2 = vl(n + 100); p2[0] = 1; for (int i = 1; i < (int)p2.size(); i++) { p2[i] = p2[i - 1] * 2 % MOD; } create(0, 0, n); forn(it, q) { int ty, l, r, add; scanf("%d %d %d", &ty, &l, &r); r++; if (ty == 1) { scanf("%d", &add); updateSegm(0, 0, n, l, r, add); } else { vi c = rmq(0, 0, n, l, r); printf("%d\n", calc(c)); } } return 0; }