#include using namespace std; const int MOD=1000000007; int N, Q; char S[100002]; struct node { int lazy; int cnt[26]; } seg[262144], id; node combine(node a, node b) { node c; c.lazy=0; for(int i=0; i<26; i++) c.cnt[i]=a.cnt[(i+a.lazy)%26]+b.cnt[(i+b.lazy)%26]; return c; } void apply(int idx, int v) { seg[idx].lazy+=v; } void down(int idx) { if(seg[idx].lazy) { apply(idx*2, seg[idx].lazy); apply(idx*2+1, seg[idx].lazy); node c; c.lazy=0; for(int i=0; i<26; i++) c.cnt[i]=seg[idx].cnt[(i+seg[idx].lazy)%26]; seg[idx]=c; } } void build(int idx, int begin, int end) { if(begin==end) seg[idx].cnt[S[begin]-'a']++; else { int mid=(begin+end)/2; build(idx*2, begin, mid); build(idx*2+1, mid+1, end); seg[idx]=combine(seg[idx*2], seg[idx*2+1]); } } void update(int idx, int begin, int end, int l, int r, int v) { if(r0; b/=2) { if(b&1) ret=1LL*ret*a%MOD; a=1LL*a*a%MOD; } return ret; } int getans(node n) { int e=0; for(int i=0; i<26; i++) if(n.cnt[i]>0) e+=n.cnt[i]-1; int f=1; for(int i=0; i<26; i++) if(n.cnt[i]>0) f++; return ((1LL*powmod(2, e)*f)%MOD-1+MOD)%MOD; } int main() { scanf("%d%d", &N, &Q); scanf("%s", S+1); build(1, 1, N); while(Q--) { int t; scanf("%d", &t); if(t==1) { int a, b, c; scanf("%d%d%d", &a, &b, &c); update(1, 1, N, a+1, b+1, (26-(c%26))%26); } else { int a, b; scanf("%d%d", &a, &b); printf("%d\n", getans(query(1, 1, N, a+1, b+1))); } } return 0; }