You've got a string s = s1s2... s|s| of length |s|, consisting of lowercase English letters. There also are q queries, each query is described by two integers li, ri (1 ≤ li ≤ ri ≤ |s|). The answer to the query is the number of substrings of string s[li... ri], which are palindromes.

String s[l... r] = slsl + 1... sr (1 ≤ l ≤ r ≤ |s|) is a substring of string s = s1s2... s|s|.

String t is called a palindrome, if it reads the same from left to right and from right to left. Formally, if t = t1t2... t|t| = t|t|t|t| - 1... t1.

Input

The first line contains string s (1 ≤ |s| ≤ 5000). The second line contains a single integer q (1 ≤ q ≤ 106) — the number of queries. Next q lines contain the queries. The i-th of these lines contains two space-separated integers li, ri (1 ≤ li ≤ ri ≤ |s|) — the description of the i-th query.

It is guaranteed that the given string consists only of lowercase English letters.

Output

Print q integers — the answers to the queries. Print the answers in the order, in which the queries are given in the input. Separate the printed numbers by whitespaces.

Examples

Input

caaaba
5
1 1
1 4
2 3
4 6
4 5


Output

1
7
3
4
2

Note

Consider the fourth query in the first test case. String s[4... 6] = «aba». Its palindrome substrings are: «a», «b», «a», «aba».
import java.io.*;
import java.util.*;
import java.math.*;

public class P245H {

  final int HASH_PARAM = 31; // java's hash code param

  int n;
  String s = null;
  int [] ht = null;
  int [][] sum = null;

  int palindromes(int l, int r) {
    if (l > r) {
      return 0;
    }

    if (l == r) {
      return 1;
    }

    if (sum[l][r - l] >= 0) {
      return sum[l][r - l];
    }

    sum[l][r - l] = palindromes(l, r - 1) + palindromes(l + 1, r) -
                    palindromes(l + 1, r - 1) + (ht[l * n + r] == ht[r * n + l] ? 1 : 0);

    return sum[l][r - l];
  }

  void prepareHT(String s) {
    ht = new int [n * n];

    for (int i = 0; i < n; i++) {
      ht[i * n + i] = s.charAt(i);
    }

    for (int i = 1; i < n; i++) {
      for (int j = i - 1; j >= 0; j--) {
        ht[j * n + i] = ht[j * n + i - 1] * HASH_PARAM + ht[i * n + i];
      }
    }

    for (int i = n - 2; i >= 0; i--) {
      for (int j = i + 1; j < n; j++) {
        ht[j * n + i] = ht[j * n + i + 1] * HASH_PARAM + ht[i * n + i];
      }
    }
  }

  @SuppressWarnings("unchecked")
  public void run() throws Exception {
    s = nextLine();
    n = s.length();

    prepareHT(s);

    sum = new int [n][];
    for (int i = 0; i < n; i++) {
      sum[i] = new int [n - i];
      Arrays.fill(sum[i], -1);
    }
    
    int q = nextInt();
    while ((q--) > 0) {
      int l = nextInt() - 1;
      int r = nextInt() - 1;
      println(palindromes(l, r));
    }
  }

  public static void main(String... args) throws Exception {
    br = new BufferedReader(new InputStreamReader(System.in));
    pw = new PrintWriter(new BufferedOutputStream(System.out));
    new P245H().run();
    br.close();
    pw.close();
  }

  static BufferedReader br;
  static PrintWriter pw;
  StringTokenizer stok;

  String nextToken() throws IOException {
    while (stok == null || !stok.hasMoreTokens()) {
      String s = br.readLine();
      if (s == null) {
        return null;
      }
      stok = new StringTokenizer(s);
    }
    return stok.nextToken();
  }

  void print(byte b) {
    print("" + b);
  }

  void print(int i) {
    print("" + i);
  }

  void print(long l) {
    print("" + l);
  }

  void print(double d) {
    print("" + d);
  }

  void print(char c) {
    print("" + c);
  }

  void print(Object o) {
    if (o instanceof int[]) {
      print(Arrays.toString((int [])o));
    } else if (o instanceof long[]) {
      print(Arrays.toString((long [])o));
    } else if (o instanceof char[]) {
      print(Arrays.toString((char [])o));
    } else if (o instanceof byte[]) {
      print(Arrays.toString((byte [])o));
    } else if (o instanceof short[]) {
      print(Arrays.toString((short [])o));
    } else if (o instanceof boolean[]) {
      print(Arrays.toString((boolean [])o));
    } else if (o instanceof float[]) {
      print(Arrays.toString((float [])o));
    } else if (o instanceof double[]) {
      print(Arrays.toString((double [])o));
    } else if (o instanceof Object[]) {
      print(Arrays.toString((Object [])o));
    } else {
      println("" + o);
    }
  }

  void print(String s) {
    pw.print(s);
  }

  void println(byte b) {
    println("" + b);
  }

  void println(int i) {
    println("" + i);
  }

  void println(long l) {
    println("" + l);
  }

  void println(double d) {
    println("" + d);
  }

  void println(char c) {
    println("" + c);
  }

  void println(Object o) {
    print(o);
    println("");
  }

  void println(String s) {
    pw.println(s);
  }

  int nextInt() throws IOException {
    return Integer.parseInt(nextToken());
  }

  long nextLong() throws IOException {
    return Long.parseLong(nextToken());
  }

  double nextDouble() throws IOException {
    return Double.parseDouble(nextToken());
  }

  char nextChar() throws IOException {
    return (char) (br.read());
  }

  String next() throws IOException {
    return nextToken();
  }

  String nextLine() throws IOException {
    return br.readLine();
  }

  int [] readInt(int size) throws IOException {
    int [] array = new int [size];
    for (int i = 0; i < size; i++) {
      array[i] = nextInt();
    }
    return array;
  }

  long [] readLong(int size) throws IOException {
    long [] array = new long [size];
    for (int i = 0; i < size; i++) {
      array[i] = nextLong();
    }
    return array;
  }

  double [] readDouble(int size) throws IOException {
    double [] array = new double [size];
    for (int i = 0; i < size; i++) {
      array[i] = nextDouble();
    }
    return array;
  }

}