import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.InputMismatchException; import java.util.TreeMap; public class Solution1 implements Runnable { static final int MAX = 1000000007; static class InputReader { private InputStream stream; private byte[] buf = new byte[1024]; private int curChar; private int numChars; private SpaceCharFilter filter; private BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 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() { String str = ""; try { str = br.readLine(); } catch (IOException e) { e.printStackTrace(); } return str; } 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 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 double nextDouble() { int c = read(); while (isSpaceChar(c)) c = read(); int sgn = 1; if (c == '-') { sgn = -1; c = read(); } double res = 0; while (!isSpaceChar(c) && c != '.') { if (c == 'e' || c == 'E') return res * Math.pow(10, nextInt()); if (c < '0' || c > '9') throw new InputMismatchException(); res *= 10; res += c - '0'; c = read(); } if (c == '.') { c = read(); double m = 1; while (!isSpaceChar(c)) { if (c == 'e' || c == 'E') return res * Math.pow(10, nextInt()); if (c < '0' || c > '9') throw new InputMismatchException(); m /= 10; res += (c - '0') * m; c = read(); } } return res * sgn; } 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 boolean isSpaceChar(int c) { if (filter != null) return filter.isSpaceChar(c); return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1; } public String next() { return readString(); } public interface SpaceCharFilter { public boolean isSpaceChar(int ch); } } public static void main(String args[]) throws Exception { new Thread(null, new Solution1(),"Solution1",1<<26).start(); } public static int gcd(int a, int b) { if (a == 0) return b; return gcd(b%a, a); } static int lcm(int a, int b) { return (a*b)/gcd(a, b); } static int max= -1; public void run() { InputReader sc= new InputReader(System.in); PrintWriter w= new PrintWriter(System.out); fact(); String s = sc.next(); int q = sc.nextInt(); Node[] n = new Node[s.length()+1]; n[0] = new Node(); Arrays.fill(n[0].arr,0); for(int i = 1;i <= s.length();i++){ n[i] = new Node(); n[i].arr[s.charAt(i-1)-97]++; n[i] = merge(n[i].arr,n[i-1].arr); } while(q-- > 0){ int l = sc.nextInt(); int r = sc.nextInt(); long ans = 0; int[] arr = sub(n[l-1].arr,n[r].arr); int maxLength = 0; boolean flag = false; int count = 0; int[] rem = new int[26]; for(int i = 0;i < arr.length;i++){ if(arr[i] % 2 == 0){ maxLength += arr[i]/2; }else{ count++; maxLength += arr[i]/2; } rem[i] = arr[i]/2; } long an = 0; an = fact[maxLength]; for(int i = 0;i < rem.length;i++){ if(rem[i] != 0){ an = (an * modInverse(fact[rem[i]],MAX))%MAX; } } if(count != 0){ an = (an*count)%MAX; } w.println(an); } w.close(); } long[] fact = new long[200001]; void fact(){ fact[0] = 1; for(int i = 1;i < fact.length;i++){ fact[i] = (fact[i-1]*i)%MAX; } } static long modInverse(long a,long m) { long m0 = m, t, q; long x0 = 0, x1 = 1; if (m == 1) return 0; while (a > 1) { // q is quotient q = a / m; t = m; // m is remainder now, process // same as Euclid's algo m = a % m; a = t; t = x0; x0 = x1 - q * x0; x1 = t; } // Make x1 positive if (x1 < 0) x1 += m0; return x1; } int[] sub(int[] arr1,int[] arr2){ int[] temp = new int[26]; for(int i = 0;i < 26;i++){ temp[i] = arr2[i] - arr1[i]; } return temp; } Node merge(int[] arr1,int[] arr2){ int[] temp = new int[26]; for(int i = 0;i < 26;i++){ temp[i] = arr1[i] + arr2[i]; } Node n = new Node(); n.arr = temp; return n; } class MyNameComp implements Comparator{ @Override public int compare(Integer e1,Integer e2) { return e2.compareTo(e1); } } static class Node{ int[] arr= new int[26]; } static class Pair implements Comparable{ int a; int b; Pair(){ } Pair(int a,int b) { this.a = a; this.b = b; } public boolean equals(Object o) { Pair p = (Pair)o; return p.a==a && p.b==b; } public int compareTo(Pair p){ if(p.b == this.b){ return Integer.compare(this.a,p.a); }else{ return Integer.compare(this.b,p.b); } } public int hashCode() { return new Long(a).hashCode()*31 + new Long(a).hashCode(); } } }