#include using namespace std; #define llong long long #define long llong const int module = 1000000007; const int n_max = 100010; string A; int T[n_max * 4][26], U[n_max * 4], P2[n_max]; int R[26]; int n, q; void shift(int c[], int x) { rotate(c, c + 26 - x, c + 26); } void relax(int x, int k) { if (U[x]) { shift(T[k], U[x]); shift(T[k + 1], U[x]); U[k] = (U[k] + U[x]) % 26; U[k + 1] = (U[k + 1] + U[x]) % 26; U[x] = 0; } } void build_tree(int x, int l, int r) { if (l == r) { T[x][A[l] - 'a'] = 1; return; } int k = x * 2, mid = l + (r - l) / 2; build_tree(k, l, mid); build_tree(k + 1, mid + 1, r); for (int i = 0; i < 26; ++i) T[x][i] = T[k][i] + T[k + 1][i]; } void upd(int u, int v, int p, int x = 1, int l = 0, int r = n - 1) { if (v < l || r < u) return; if (u <= l && r <= v) { U[x] = (U[x] + p) % 26; shift(T[x], p % 26); return; } int k = x * 2, mid = l + (r - l) / 2; relax(x, k); upd(u, v, p, k, l, mid); upd(u, v, p, k + 1, mid + 1, r); for (int i = 0; i < 26; ++i) T[x][i] = T[k][i] + T[k + 1][i]; } void getr(int u, int v, int x = 1, int l = 0, int r = n - 1) { if (v < l || r < u) return; if (u <= l && r <= v) { for (int i = 0; i < 26; ++i) R[i] += T[x][i]; return; } int k = x * 2, mid = l + (r - l) / 2; relax(x, k); getr(u, v, k, l, mid); getr(u, v, k + 1, mid + 1, r); } void enter() { cin >> n >> q >> A; build_tree(1, 0, n - 1); } void init() { P2[0] = 1; for (int i = 1; i <= n; ++i) P2[i] = (P2[i - 1] * 2) % module; } void solve() { int t, x, y, k; while (q--) { cin >> t >> x >> y; if (t == 1) cin >> k, upd(x, y, k); if (t == 2) { fill_n(R, 26, 0); getr(x, y); int s = 0, c = 0; for (int i = 0; i < 26; ++i) if (R[i] > 0) s += R[i] - 1, c++; cout << ((long)P2[s] * (c + 1) + module - 1) % module << "\n"; } } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); if (ifstream("test.inp")) cin.rdbuf((new ifstream("test.inp"))->rdbuf()); enter(); init(); solve(); }