#include #define mp make_pair #define PII pair #define fi first #define se second #define pb push_back #define ll long long #define ull unsigned long long #define ui unsigned int #define sci(x) scanf("%d",&x) #define scs(s) scanf("%s",s) #define scc(c) scanf("%c",c) #define scd(d) scanf("%lf",&d) #define scld(ld) scanf("%Lf",&ld) using namespace std; //******************************************** //Error tracking #define show(args...) { vector _v = split(#args, ','); err(_v.begin(), args); } vector split(const string& s, char c) { vector v; stringstream ss(s); string x; while (getline(ss, x, c)) v.emplace_back(x); return move(v); } void err(vector::iterator it) {} template void err(vector::iterator it, T a, Args... args) { cerr << it -> substr((*it)[0] == ' ', it -> length()) << " = " << a << '\n'; err(++it, args...); } //******************************************** const int MOD = 1000000007; const int NMAX = 100005; int n,q,a[NMAX],aux[30],ans[30]; int aint[26][4*NMAX],lazy[4*NMAX]; void CreateAint(int nod, int st, int dr) { if (st == dr) aint[a[st]][nod]++; else { int mij = (st + dr) / 2; CreateAint(2*nod, st, mij); CreateAint(2*nod + 1, mij + 1, dr); for (int i = 0 ; i < 26; i++) aint[i][nod] = aint[i][2*nod] + aint[i][2*nod + 1]; } } void DOWN(int nod) { for (int i = 0; i < 26; i++) aux[(i + lazy[nod])%26] = aint[i][nod]; for (int i = 0; i < 26; i++) aint[i][nod] = aux[i]; if (2*nod + 1 < 4*NMAX) { lazy[2*nod] += lazy[nod]; lazy[2*nod + 1] += lazy[nod]; if (lazy[2*nod] >= MOD) lazy[2*nod] -= MOD; if (lazy[2*nod + 1] >= MOD) lazy[2*nod + 1] -= MOD; } //clear lazy[nod] = 0; } void Update(int nod,int st,int dr,int l,int r,int val) { if (l <= st && dr <= r) lazy[nod] = (lazy[nod] + val)%26; else { int mij = (st + dr) / 2; DOWN(nod); if (l <= mij) Update(2*nod, st, mij ,l , r, val); if (r > mij) Update(2*nod + 1, mij + 1, dr, l , r , val); DOWN(2*nod); DOWN(2*nod + 1); for (int i = 0 ; i < 26; i++) aint[i][nod] = aint[i][2*nod] + aint[i][2*nod + 1]; } } void Add(int nod, int st, int dr, int l, int r) { if (l <= st && dr <= r) { DOWN(nod); for (int i = 0; i < 26; i++) ans[i] += aint[i][nod]; } else { int mij = (st + dr) / 2; DOWN(nod); if (l <= mij) Add(2*nod, st, mij ,l , r); if (r > mij) Add(2*nod + 1, mij + 1, dr, l , r); DOWN(2*nod); DOWN(2*nod + 1); for (int i = 0 ; i < 26; i++) aint[i][nod] = aint[i][2*nod] + aint[i][2*nod + 1]; } } int Log(int x, int y) { int p = 1; while (y) { if (y & 1) p = (1LL*p*x)%MOD; x = (1LL*x*x)%MOD; y >>= 1; } return p; } int Mod(int x) { while (x >= MOD) x -= MOD; while (x < 0) x += MOD; return x; } int main() { int i; // freopen("input","r",stdin); // freopen("output","w",stdout); cin.sync_with_stdio(false); cin >> n >> q; for (i = 1; i <= n; i++) { char C; cin >> C; a[i] = C - 'a'; } CreateAint(1,1,n); int op,x,y,t; while (q--) { cin >> op >> x >> y; x++; y++; if (op == 1) { cin >> t; t %= 26; Update(1,1,n,x,y,t); } else { for (i = 0; i < 26; i++) ans[i] = 0; Add(1,1,n,x,y); int prod = 1, nr = 0; for (i = 0; i < 26; i++) if (ans[i]) { aux[i] = Log(2, ans[i] - 1); prod = (1LL*prod*aux[i])%MOD; nr++; } prod = (1LL*prod*(nr + 1))%MOD; //1 for all even, rest for every odd prod--; //take out empty subsequence if (prod < 0) prod += MOD; cout << prod << "\n"; } } return 0; }