#include #include #include #include #include #include using namespace std; #define TRACE(x) cerr << #x << " = " << x << endl #define REP(i, n) for (int i=0; i P; #define X first #define Y second const int TOUR = 1<<17, MAX = TOUR; const int MOD = 1e9 + 7; int add(int a, int b) { a += b; if (a >= MOD) a -= MOD; return a; } int sub(int a, int b) { a -= b; if (a < 0) a += MOD; return a; } int mul(int a, int b) { return (int) (((ll) a * b) % MOD); } int pot(int x, int e) { int r = 1; for (; e; x = mul(x, x), e /= 2) if (e & 1) r = mul(r, x); return r; } int inv(int x) { return pot(x, MOD - 2); } int divv(int a, int b) { return mul(a, inv(b)); } char s[MAX]; int pot2[MAX]; int n; vector t[2*TOUR]; int prop[2*TOUR]; void upd(int ind) { REP(i, 26) t[ind][i] = t[2*ind][i] + t[2*ind+1][i]; } void init() { REP(i, 2*TOUR) t[i] = vector(26, 0); REP(i, n) t[i+TOUR][s[i]-'a'] = 1; for (int i=TOUR-1; i; i--) upd(i); } void prom(int ind, int kol) { vector T = t[ind]; int kamo = kol; REP(i, 26) { t[ind][kamo] = T[i]; kamo++; if (kamo == 26) kamo = 0; } } void propag(int ind) { if (!prop[ind]) return; FOR(i, 2*ind, 2*ind+2) { prom(i, prop[ind]); prop[i] = (prop[i] + prop[ind]) % 26; } prop[ind] = 0; } void stavi(int pos, int lo, int hi, int begin, int end, int val) { if (lo >= end || hi <= begin) return; if (lo >= begin && hi <= end) { prom(pos, val); prop[pos] = (prop[pos] + val) % 26; return; } propag(pos); stavi(2*pos+0, lo, (lo+hi)/2, begin, end, val); stavi(2*pos+1, (lo+hi)/2, hi, begin, end, val); upd(pos); } vector vrati(int pos, int lo, int hi, int begin, int end) { if (lo >= end || hi <= begin) return vector(26, 0); if (lo >= begin && hi <= end) return t[pos]; propag(pos); vector A = vrati(2*pos+0, lo, (lo+hi)/2, begin, end); vector B = vrati(2*pos+1, (lo+hi)/2, hi, begin, end); REP(i, 26) A[i] += B[i]; return A; } int pref[30], suf[30]; int inv2 = inv(2); int query(int l, int r) { vector T = vrati(1, 0, TOUR, l, r + 1); int ret = 0; int umn = 1, ima = 0, ima2 = 0; REP(i, 26) { if (T[i]) { umn = mul(umn, pot2[T[i]-1]); if (T[i] > 1) ima2++; ima++; } } ret = umn; REP(i, 26) if (T[i]) ret = add(ret, umn); ret = sub(ret, 1); return ret; } int main() { pot2[0] = 1; FOR(i, 1, MAX) pot2[i] = mul(pot2[i-1], 2); int brq; scanf("%d%d %s", &n, &brq, s); init(); for (; brq; brq--) { int st, l, r; scanf("%d%d%d", &st, &l, &r); if (st == 2) printf("%d\n", query(l, r)); else { int rot; scanf("%d", &rot); rot %= 26; stavi(1, 0, TOUR, l, r + 1, rot); } } return 0; }