#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define all(x) x.begin() , x.end() #define fi first #define se second #define pb push_back #define umax( x , y ) x = max( x , (y) ) #define umin( x , y ) x = min( x , (y) ) #define For( i , a ) for(int i=1;i<=a;i++) #define ort (b+s)/2 #define y2 asrwjaelkf #define y1 asseopirwjaelkf #define set multiset using namespace std; inline int read() { int res = 0 ;int neg ; while(true){char ch = getchar();if(ch>='0' && ch<='9' || ch=='-'){if(ch=='-') neg = -1;else neg = 1 , res = ch-'0';break;} } while(true){char ch = getchar();if(ch>='0' && ch<='9') res*=10 , res+=ch-'0';else break;} return res*neg; } typedef long long Lint; typedef double db; typedef pair ii; typedef pair dd; typedef pair di; typedef pair iii; typedef pair i4; const int maxn = 100020; const int maxm = 1000020; const int MOd = 1e9 + 7; int a, H[26], b; Lint lazy[maxn*3]; int segment[maxn*3][26], n; char ar[maxn]; int com[40][40]; int mul( int a, int b ) { return (Lint)a * b % MOd; } int add( int a, int b ) { return (a+b>=MOd)? a+b-MOd:a+b; } void push( int k ) { if( lazy[k] ) { if( k < n ) { lazy[k+k] += lazy[k]; lazy[k+k+1] += lazy[k]; } for(int i=0;i<26;i++) H[(i+lazy[k])%26] = segment[k][i]; for(int i=0;i<26;i++) segment[k][i] = H[i]; lazy[k] = 0; } } int ans[26], us[100020]; void find( int k, int b, int s, int x, int y ) { push( k ); if( b > y || x > s ) return; if( x <= b && s <= y ) { for(int i=0;i<26;i++) ans[i] += segment[k][i]; return; } find( k+k, b, ort, x, y ); find( k+k+1, ort+1, s, x, y ); } void update( int k, int b, int s, int x, int y, int m ) { push( k ); if( b > y || x > s ) return; if( x <= b && s <= y ) { lazy[k] += m; push( k ); return; } update( k+k, b, ort, x, y, m ); update( k+k+1, ort+1, s, x, y, m ); for(int i=0;i<26;i++) segment[k][i] = segment[k+k][i] + segment[k+k+1][i]; return; } int main() { //freopen("asd.in.c","r",stdin); //freopen("out.txt","w",stdout); scanf("%d %d",&a,&b); scanf(" %s",ar+1); com[0][0] = 1; us[0] = 1; for(int i=1;i<=a;i++) us[i] = mul( us[i-1], 2 ); for(int i=1;i<=30;i++) { com[i][0] = 1; for(int j=1;j<=i;j++) com[i][j] = add( com[i-1][j], com[i-1][j-1] ); } n = 1; while( n < a ) n <<= 1; for(int i=1;i<=a;i++) { segment[i+n-1][ar[i] - 'a']++; } for(int k=n-1;k>=1;k--) for(int i=0;i<26;i++) segment[k][i] = segment[k+k][i] + segment[k+k+1][i]; for(int l=1;l<=b;l++) { int tp, j, k; scanf("%d %d %d",&tp,&j,&k); j++, k++; if( tp == 2 ) { memset( ans, 0, sizeof( ans ) ); find( 1, 1, n, j, k ); int ret = 1, h = 1; for(int i=0;i<26;i++) if( ans[i] ) h++, ret = mul( ret, us[ans[i]-1] );//, printf("-- asd %d %d %d\n",l,i,ans[i]); ret = mul( ret, h ); ret--; if( ret < 0 ) ret += MOd; printf("%d\n",ret); } if( tp == 1 ) { int x; scanf("%d",&x); update( 1, 1, n, j, k, x ); } } return 0; }