import java.util.*; import java.io.*; import java.math.*; public class Main1{ static long mod=(long)Math.pow(10,9)+7; //static long answers[]=new long[1000001]; public static void main(String[] args){ InputReader in = new InputReader(System.in); PrintWriter w = new PrintWriter(System.out); int n=in.nextInt(); int q=in.nextInt(); StringBuilder str=new StringBuilder(in.nextLine()); while(q-->0){ int type=in.nextInt(); switch(type){ case 1: int i=in.nextInt(); int j=in.nextInt(); int t=in.nextInt(); for(int k=i;k<=j;k++){ char c=str.charAt(k); long num=c; t=t-((t/26)*26); num=c+t; if(num>122){ num=num-26; } str.setCharAt(k,(char)num); } //w.println(str); break; case 2: int i1=in.nextInt(); int j1=in.nextInt(); int map[]=new int[26]; for(int k1=i1;k1<=j1;k1++){ map[str.charAt(k1)-'a']++; } int x=0,y=0; for(int z=0;z<26;z++){ if(map[z]%2==0){ y+=(map[z]/2); }else{ x++; y+=((int)(map[z]/2)); } } /*w.println(x+" "+y+" "+(j1-i1+1)); long ans=0; if(y>0){ }*/ w.println(((((long)(j1-i1+1))%mod)+((1+x)%mod)*(((long)Math.pow(2,y)-(long)(1))%mod))%mod); break; } } w.close(); } static boolean isPalin(String str){ int map[]=new int[26]; int nn=0; for(int i=0;i1){ return false; } } return true; } static class InputReader { private final InputStream stream; private final byte[] buf = new byte[8192]; private int curChar, numChars; private SpaceCharFilter filter; public InputReader(InputStream stream) { this.stream = stream; } public int read() { if (numChars == -1) { throw new InputMismatchException(); } if (curChar >= numChars) { curChar = 0; try { numChars = stream.read(buf); } catch (IOException e) { throw new InputMismatchException(); } if (numChars <= 0) { return -1; } } return buf[curChar++]; } public String nextLine() { int c = read(); while (isSpaceChar(c)) { c = read(); } StringBuilder res = new StringBuilder(); do { res.appendCodePoint(c); c = read(); } while (!isEndOfLine(c)); return res.toString(); } public String readString() { int c = read(); while (isSpaceChar(c)) { c = read(); } StringBuilder res = new StringBuilder(); do { res.appendCodePoint(c); c = read(); } while (!isSpaceChar(c)); return res.toString(); } public long nextLong() { int c = read(); while (isSpaceChar(c)) { c = read(); } int sgn = 1; if (c == '-') { sgn = -1; c = read(); } long res = 0; do { if (c < '0' || c > '9') { throw new InputMismatchException(); } res *= 10; res += c - '0'; c = read(); } while (!isSpaceChar(c)); return res * sgn; } public int nextInt() { int c = read(); while (isSpaceChar(c)) { c = read(); } int sgn = 1; if (c == '-') { sgn = -1; c = read(); } int res = 0; do { if (c < '0' || c > '9') { throw new InputMismatchException(); } res *= 10; res += c - '0'; c = read(); } while (!isSpaceChar(c)); return res * sgn; } public int[] nextIntArray(int n) { int[] arr = new int[n]; for (int i = 0; i < n; i++) { arr[i] = nextInt(); } return arr; } public long[] nextLongArray(int n) { long[] arr = new long[n]; for (int i = 0; i < n; i++) { arr[i] = nextLong(); } return arr; } public boolean isSpaceChar(int c) { if (filter != null) return filter.isSpaceChar(c); return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1; } private boolean isEndOfLine(int c) { return c == '\n' || c == '\r' || c == -1; } public interface SpaceCharFilter { public boolean isSpaceChar(int ch); } } }