using namespace std; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define S(x) scanf("%d",&x) #define S2(x,y) scanf("%d%d",&x,&y) #define wl(n) while(n--) #define ll long long #define bitcnt(x) __builtin_popcount(x) #define P(x) printf("%d\n",x) #define PB push_back #define MP make_pair #define fl(i,n) for(i=0;i=a;i--) #define mem(a,i) memset(a,i,sizeof(a)) #define F first #define S1 second typedef pair P; vector v1; pair p1; #define MOD 1000000007 #define debug(x) printf("####%d####\n",x); #define nl printf("\n"); #define str string int a[27]; string s; int dp[27][3]; ll pow1(ll x,ll y) { if(y==0) return 1; ll temp= pow1(x,y/2)%MOD; if(y%2==0) return (temp*temp)%MOD; else return (((temp*temp)%MOD)*x)%MOD; } int func(int idx,int flag) { if(idx==26) return 1; int &ans=dp[idx][flag]; if(ans!=-1) return ans; if(a[idx]==0) return func(idx+1,flag); ans=0; ans=(ans+(pow1(2ll,a[idx]-1)*(func(idx+1,flag)))%MOD)%MOD; if(!flag) ans=(ans+(pow1(2ll,a[idx]-1)*(func(idx+1,1)))%MOD)%MOD; return ans; } int tree[400001][27],lazy[400001]; void create(int start,int end,int index) { int i; if(start==end) { tree[index][s[start]-'a']=1; return; } int mid=(start+(end-start)/2); create(start,mid,2*index+1); create(mid+1,end,2*index+2); fl(i,26) tree[index][i]=tree[2*index+1][i]+tree[2*index+2][i]; return; } void shift(int a[],int val) { int i,b[27]; fl(i,26) b[i]=a[i]; fl(i,26) a[(i+val)%26]=b[i]; } void propagate(int start,int end,int index) { shift(tree[index],lazy[index]); if(start!=end) { lazy[2*index+1]=(lazy[2*index+1]+lazy[index])%26; lazy[2*index+2]=(lazy[2*index+2]+lazy[index])%26; } lazy[index]=0; return; } void update(int start,int end,int q1,int q2,int index,int val) { int i; if(lazy[index]>0) propagate(start,end,index); if(q2end) return; if(q1<=start&&q2>=end) { lazy[index]=(lazy[index]+val)%26; propagate(start,end,index); return; } int mid=(start+(end-start)/2); update(start,mid,q1,q2,2*index+1,val); update(mid+1,end,q1,q2,2*index+2,val); fl(i,26) tree[index][i]=tree[2*index+1][i]+tree[2*index+2][i]; return; } int getsum(int start,int end,int q1,int q2,int index,int val) { if(lazy[index]>0) propagate(start,end,index); if(q2end) return 0; if(q1<=start&&q2>=end) return tree[index][val]; int mid=(start+(end-start)/2); int an1=getsum(start,mid,q1,q2,2*index+1,val); int an2=getsum(mid+1,end,q1,q2,2*index+2,val); an1=(an1+an2); return an1; } int main() { //std::ios_base::sync_with_stdio(false); int t; int n,i,j,k,m,l,q; S2(n,q); cin>>s; create(0,n-1,0); wl(q) { S(l); if(l==1) { int val; S2(j,k); S(val); update(0,n-1,j,k,0,val); } else { S2(j,k); fl(i,26) a[i]=getsum(0,n-1,j,k,0,i); mem(dp,-1); int ans=func(0,0); ans=(ans-1+MOD)%MOD; P(ans); } } return 0; }