#include using namespace std; typedef long long ll; #define F first #define S second const int MAXN = 1e5 + 10; const int MOD = 1e9 + 7; const int C = 26; struct Node{ int cnt[C]; Node(){ for (int i = 0; i < C; i++) cnt[i] = 0; } }; int n, q; string s; Node weed[4 * MAXN], nl; int nut[4 * MAXN], pw[MAXN]; void plant(int v, int b, int e){ if (e - b == 1){ weed[v].cnt[s[b] - 'a']++; return; } int mid = b + e >> 1; plant(v<<1, b, mid); plant(v<<1^1, mid, e); for (int i = 0; i < C; i++) weed[v].cnt[i] = weed[v<<1].cnt[i] + weed[v<<1^1].cnt[i]; } void absorb(int v){ if (!nut[v]) return; nut[v<<1] += nut[v]; if (nut[v<<1] >= C) nut[v<<1] -= C; nut[v<<1^1] += nut[v]; if (nut[v<<1^1] >= C) nut[v<<1^1] -= C; rotate(weed[v<<1].cnt, weed[v<<1].cnt + (C - nut[v]), weed[v<<1].cnt + C); rotate(weed[v<<1^1].cnt, weed[v<<1^1].cnt + (C - nut[v]), weed[v<<1^1].cnt + C); nut[v] = 0; } void water(int v, int b, int e, int l, int r, int x){ if (l <= b && e <= r){ rotate(weed[v].cnt, weed[v].cnt + (C - x), weed[v].cnt + C); nut[v] += x; if (nut[v] >= C) nut[v] -= C; return; } if (r <= b || e <= l) return; int mid = b + e >> 1; absorb(v); water(v<<1, b, mid, l, r, x); water(v<<1^1, mid, e, l, r, x); for (int i = 0; i < C; i++) weed[v].cnt[i] = weed[v<<1].cnt[i] + weed[v<<1^1].cnt[i]; } Node merge(Node a, Node b){ for (int i = 0; i < C; i++) a.cnt[i] += b.cnt[i]; return a; } Node smoke(int v, int b, int e, int l, int r){ if (l <= b && e <= r) return weed[v]; if (r <= b || e <= l) return nl; int mid = b + e >> 1; absorb(v); return merge(smoke(v<<1, b, mid, l, r), smoke(v<<1^1, mid, e, l, r)); } int main(){ ios::sync_with_stdio(false); cin.tie(0); cin >> n >> q; cin >> s; plant(1, 0, n); pw[0] = 1; for (int i = 1; i < MAXN; i++){ pw[i] = pw[i - 1]<<1; if (pw[i] >= MOD) pw[i] -= MOD; } while (q--){ int type; cin >> type; if (type == 1){ int l, r, x; cin >> l >> r >> x, r++; x %= C; if (x) water(1, 0, n, l, r, x); } else{ int l, r; cin >> l >> r, r++; Node v = smoke(1, 0, n, l, r); int ans = 0; int x = 1, y = 0; for (int i = 0; i < C; i++){ ans = (ans + 1ll * (pw[v.cnt[i]]+MOD-1) * x) % MOD; if (v.cnt[i]) ans = (ans + 1ll * (pw[v.cnt[i]-1]+ MOD - 1) * y) % MOD; int temp = x; x = 1ll * x * pw[max(0, v.cnt[i]-1)] % MOD; y = 1ll * y * pw[max(0, v.cnt[i] - 1)] % MOD; if (v.cnt[i]) y = (y + 1ll * temp * pw[v.cnt[i] - 1]) % MOD; } cout << ans << "\n"; } } return 0; }