#include using namespace std; #define sim template < class c #define ris return * this #define dor > debug & operator << #define eni(x) sim > typename \ enable_if(0) x 1, debug&>::type operator<<(c i) { sim > struct rge { c b, e; }; sim > rge range(c i, c j) { return rge{i, j}; } sim > auto dud(c* x) -> decltype(cerr << *x, 0); sim > char dud(...); struct debug{ #ifdef LOCAL ~debug() { cerr << endl; } eni(!=) cerr << boolalpha << i; ris; } eni(==) ris << range(begin(i), end(i)); } sim, class b dor(pair < b, c > d) { ris << "(" << d.first << ", " << d.second << ")"; } sim dor(rge d) { *this << "["; for (auto it = d.b; it != d.e; ++it) *this << ", " + 2 * (it == d.b) << *it; ris << "]"; } #else sim dor(const c &) { ris; } #endif }; #define imie(x) " [" << #x ": " << (x) << "] " int tmp[26]; struct S { int t[26]; int toPush; S() { for(int i = 0; i < 26; ++i) t[i] = 0; toPush = 0; } S operator + (const S & b) const { S ans; for(int j = 0; j < 26; ++j) ans.t[j] = t[j] + b.t[j]; return ans; } void move(int x) { toPush += x; for(int i = 0; i < 26; ++i) tmp[(i+x)%26] = t[i]; for(int i = 0; i < 26; ++i) t[i] = tmp[i]; } }; const int pot = 128 * 1024; const int mod = 1e9 + 7; S tr[2*pot]; char sl[pot]; typedef long long ll; void rec(int id, int q_low, int q_high, int low, int high, int move, S & ans) { if(q_high < low || high < q_low) return; if(q_low <= low && high <= q_high) { debug() << imie(move); debug() << imie(id) << imie(q_low) << imie(q_high) << imie(low) << imie(high); if(move) tr[id].move(move); else ans = ans + tr[id]; return; } assert(id < pot); tr[2*id].move(tr[id].toPush); tr[2*id+1].move(tr[id].toPush); tr[id].toPush = 0; rec(2 * id, q_low, q_high, low, (low + high) / 2, move, ans); rec(2 * id + 1, q_low, q_high, (low + high) / 2 + 1, high, move, ans); tr[id] = tr[2*id] + tr[2*id+1]; } int memo[pot]; int main() { memo[0] = 1; for(int i = 1; i < pot; ++i) memo[i] = 2 * memo[i-1] % mod; int n, q; scanf("%d%d", &n, &q); scanf("%s", sl); for(int i = 0; i < n; ++i) tr[pot+i].t[sl[i]-'a']++; for(int i = pot - 1; i >= 1; --i) tr[i] = tr[2*i] + tr[2*i+1]; while(q--) { int type, low, high, move = 0; scanf("%d%d%d", &type, &low, &high); S ans; if(type == 1) scanf("%d", &move); move %= 26; rec(1, low, high, 0, pot - 1, move, ans); if(type == 2) { int total = mod - 1; int one = 1, cnt = 0; for(int i = 0; i < 26; ++i) if(ans.t[i]) { ++cnt; one = (ll) one * memo[ans.t[i]-1] % mod; } total = (total + (ll) (cnt + 1) * one) % mod; printf("%d\n", total); } } }