#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int n;
string s;
int asd[maxn];
int asdf[maxn];
int lcp[maxn];
int rig[maxn];
int lef[maxn];
int letters[maxn][26];
int tree[4 * maxn];
int tree_lcp[4 * maxn];
int spars[maxn][30];
int pos[maxn];
int suf[maxn];
int c[maxn];
int last[26];
int sp[maxn][20];
int st[maxn];
pair<pair<int, int>, int> t[maxn];
struct der {
  int x;
  int type;
  int len;
};
vector<der> vec, ve;
multiset<int> curr;
long long h[maxn];
long long p[maxn];
long long base = 200033;
long long h1[maxn];
long long p1[maxn];
long long base1 = 200017;
void fast() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
}
void letter() {
  int i, j, a;
  for (i = 0; i < n - 1; i++) {
    letters[i][s[i] - 'a'] = 1;
  }
  for (i = 1; i < n - 1; i++) {
    for (j = 0; j < 26; j++) {
      letters[i][j] += letters[i - 1][j];
    }
  }
  for (i = 0; i < 26; i++) {
    last[i] = -1;
  }
  for (i = 0; i < n - 1; i++) {
    a = s[i] - 'a';
    asdf[i] = last[a];
    last[a] = i;
  }
  for (i = 0; i < 26; i++) {
    last[i] = n;
  }
  for (i = n - 2; i >= 0; i--) {
    a = s[i] - 'a';
    asd[i] = last[a];
    last[a] = i;
  }
}
void find_sufmas() {
  int i, j;
  for (i = 0; i < n; i++) c[i] = s[i] - 'a' + 1;
  c[n - 1] = -300;
  for (i = 1; i < n; i <<= 1) {
    for (j = 0; j < n; j++) {
      t[j] = {{c[j], c[(i + j) % n]}, j};
    }
    sort(t, t + n);
    int cnt = 0;
    for (j = 0; j < n; j++) {
      if (j && t[j].first != t[j - 1].first) cnt++;
      c[t[j].second] = cnt;
    }
  }
  for (i = 0; i < n; i++) {
    suf[c[i]] = i;
  }
}
void find_lcp() {
  int i;
  for (i = 0; i < n; i++) {
    pos[suf[i]] = i;
  }
  int k = 0;
  for (i = 0; i < n; i++) {
    if (pos[i] == n - 1) {
      k = 0;
      continue;
    }
    int j = suf[pos[i] + 1];
    while (i + k < n && j + k < n && s[i + k] == s[j + k]) k++;
    lcp[pos[i]] = k;
    if (k) k--;
  }
}
void build_lcp(int l, int r, int v) {
  if (l == r) {
    tree_lcp[v] = lcp[r - 1];
  } else {
    int m = (r + l) / 2;
    build_lcp(l, m, v * 2);
    build_lcp(m + 1, r, v * 2 + 1);
    tree_lcp[v] = min(tree_lcp[v * 2], tree_lcp[v * 2 + 1]);
  }
}
int get_get_lcp(int l, int r, int tl, int tr, int v) {
  if (l == tl && r == tr) {
    return tree_lcp[v];
  } else {
    int m = (r + l) / 2;
    if (tr <= m) {
      return get_get_lcp(l, m, tl, tr, v * 2);
    } else if (tl > m) {
      return get_get_lcp(m + 1, r, tl, tr, v * 2 + 1);
    } else {
      return min(get_get_lcp(l, m, tl, m, v * 2),
                 get_get_lcp(m + 1, r, m + 1, tr, v * 2 + 1));
    }
  }
}
int get_lcp(int a, int b) {
  if (pos[a] > pos[b]) swap(a, b);
  a = pos[a], b = pos[b] - 1;
  int len = b - a + 1;
  len = st[len];
  return min(sp[a][len], sp[b - (1 << len) + 1][len]);
}
bool check(long long len, long long a, long long b) {
  if (a > b) swap(a, b);
  long long l = a - len + 1;
  long long r = b - len + 1;
  long long h0 = h[a];
  if (l) h0 -= h[l - 1] * p[len];
  long long h2 = h[b];
  if (r) h2 -= h[r - 1] * p[len];
  long long h3 = h1[a];
  if (l) h3 -= h1[l - 1] * p1[len];
  long long h4 = h1[b];
  if (r) h4 -= h1[r - 1] * p1[len];
  return h0 == h2 && h3 == h4;
}
int get_rlcp(int a, int b) {
  long long l = 0, r = min(a, b) + 2;
  while (r - l > 1) {
    long long m = (r + l) / 2;
    if (check(m, a, b)) {
      l = m;
    } else {
      r = m;
    }
  }
  return l;
}
void fun_tondem(int l, int r) {
  if (r == l) return;
  if (l + 1 == r) {
    if (s[l] == s[r]) {
      rig[l] = r;
      lef[r] = l;
    }
    return;
  }
  if (l + 2 == r) {
    if (s[l] == s[l + 1]) {
      rig[l] = l + 1;
      lef[l + 1] = l;
    }
    if (s[l + 1] == s[r]) {
      rig[l + 1] = r;
      lef[r] = l + 1;
    }
    return;
  }
  int mid = (l + r) / 2;
  int i, j;
  for (i = l; i <= mid; i++) {
    if (get_lcp(i, mid + 1) + i - 1 >= mid) {
      int a = i + (mid - i + 1) * 2 - 1;
      rig[i] = min(rig[i], a);
      lef[a] = max(lef[a], i);
    }
  }
  for (i = l + 1; i <= mid - 1; i++) {
    int len = mid - i + 1;
    int tl = max(1, len - get_lcp(i, mid + 1));
    int tr = min({len - 1, get_rlcp(mid, i - 1), i - l});
    if (tl <= tr) {
      vec.push_back({i - tr, 0, len});
      vec.push_back({i - tl + 1, 1, len});
      ve.push_back({i - tr + 2 * len - 1 - 1, 0, len});
      ve.push_back({i - tl + 2 * len - 1, 1, len});
    }
  }
  for (i = mid + 2; i < r; i++) {
    int len = i - (mid + 1) + 1;
    int tl = max({1, len - get_lcp(mid + 1, i + 1), len - r + i});
    int tr = min(len - 1, get_rlcp(mid, i));
    if (tl <= tr) {
      vec.push_back({mid - tr + 1, 0, len});
      vec.push_back({mid - tl + 1 + 1, 1, len});
      ve.push_back({mid - tr + 1 + 2 * len - 1 - 1, 0, len});
      ve.push_back({mid - tl + 1 + 2 * len - 1, 1, len});
    }
  }
  fun_tondem(l, mid);
  fun_tondem(mid + 1, r);
}
bool cmp(der a, der b) {
  if (a.x == b.x) {
    return a.type < b.type;
  }
  return a.x < b.x;
}
bool cmp1(der a, der b) {
  if (a.x == b.x) {
    return a.type > b.type;
  }
  return a.x > b.x;
}
void find_tondem() {
  int i, j;
  for (i = 0; i < n; i++) {
    rig[i] = n + 3;
    lef[i] = -1;
  }
  fun_tondem(0, n - 1);
  sort(vec.begin(), vec.end(), cmp);
  j = 0;
  for (i = 0; i < n; i++) {
    while (j < vec.size() && vec[j].x == i) {
      if (vec[j].type == 0) {
        curr.insert(vec[j].len);
      } else {
        curr.erase(curr.find(vec[j].len));
      }
      j++;
    }
    if (curr.size()) {
      rig[i] = min(rig[i], i + *curr.begin() * 2 - 1);
    }
  }
  sort(ve.begin(), ve.end(), cmp1);
  curr.clear();
  j = 0;
  for (i = n - 1; i >= 0; i--) {
    while (j < ve.size() && ve[j].x == i) {
      if (ve[j].type == 1) {
        curr.insert(ve[j].len);
      } else {
        curr.erase(curr.find(ve[j].len));
      }
      j++;
    }
    if (curr.size()) {
      lef[i] = max(lef[i], i - *curr.begin() * 2 + 1);
    }
  }
}
bool chk_letters(int l, int r) {
  for (int i = 0; i < 26; i++) {
    int a = letters[r][i];
    if (l) a -= letters[l - 1][i];
    if (a > 1) return true;
  }
  return false;
}
bool chk_1(int l, int r) {
  int n = r - l + 1;
  int nn = n;
  for (int i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      while (n % i == 0) {
        n /= i;
      }
      if (nn / i == nn) continue;
      if (get_lcp(l, l + nn / i) + l + nn / i - 1 >= r) {
        return true;
      }
    }
  }
  if (nn / n != nn) {
    if (get_lcp(l, l + nn / n) + l + nn / n - 1 >= r) {
      return true;
    }
  }
  return false;
}
bool find_border(int l, int r) {
  int sq = 500;
  int a, b;
  for (int i = l; (i - l + 1) * 2 <= r - l + 1 && i <= sq + l; i++) {
    a = l, b = r - (i - l);
    if (get_lcp(a, b) >= i - l + 1) {
      return true;
    }
  }
  a = pos[l];
  for (int i = max(0, a - sq); i <= min(n - 1, a + sq); i++) {
    b = suf[i];
    if (b > l && b <= r && (r - b + 1) * 2 <= r - l + 1 &&
        l + (r - b + 1) - 1 < b) {
      if (get_lcp(l, b) >= r - b + 1) {
        return true;
      }
    }
  }
  return false;
}
bool chk_2(int a, int b) {
  if (rig[a] <= b || lef[b] >= a) {
    return true;
  }
  return find_border(a, b);
}
void build_tondem(int l, int r, int v) {
  if (l == r) {
    tree[v] = rig[r - 1];
  } else {
    int m = (r + l) / 2;
    build_tondem(l, m, v * 2);
    build_tondem(m + 1, r, v * 2 + 1);
    tree[v] = min(tree[v * 2], tree[v * 2 + 1]);
  }
}
int get_tondem(int l, int r, int tl, int tr, int v) {
  if (l == tl && r == tr) {
    return tree[v];
  } else {
    int m = (r + l) / 2;
    if (tr <= m) {
      return get_tondem(l, m, tl, tr, v * 2);
    } else if (tl > m) {
      return get_tondem(m + 1, r, tl, tr, v * 2 + 1);
    } else {
      return min(get_tondem(l, m, tl, m, v * 2),
                 get_tondem(m + 1, r, m + 1, tr, v * 2 + 1));
    }
  }
}
int min_tondem(int l, int r) {
  l++, r++;
  return get_tondem(1, n, l, r, 1);
}
bool chk_3(int a, int b) {
  if (asd[a] <= b || asdf[b] >= a) {
    return true;
  }
  return (min_tondem(a, b) <= b);
}
int get_ans(int a, int b) {
  a--, b--;
  if (!chk_letters(a, b)) {
    return -1;
  }
  if (chk_1(a, b)) {
    return 1;
  }
  if (chk_2(a, b)) {
    return 2;
  }
  if (chk_3(a, b)) {
    return 3;
  }
  return 4;
}
void count_hp(string s) {
  int n = s.size();
  h[0] = s[0] - 'a' + 1;
  h1[0] = s[0] - 'a' + 1;
  for (int i = 1; i < n; i++) {
    h[i] = h[i - 1] * base + s[i] - 'a' + 1;
    h1[i] = h1[i - 1] * base1 + s[i] - 'a' + 1;
  }
  p[0] = 1;
  p1[0] = 1;
  for (int i = 1; i <= n; i++) {
    p[i] = p[i - 1] * base;
    p1[i] = p1[i - 1] * base1;
  }
}
void find_spars(int n) {
  int a = 1;
  int b = 0;
  int i, j;
  st[1] = 0;
  for (i = 2; i <= n - 1; i++) {
    st[i] = st[i / 2] + 1;
  }
  for (i = 0; i < n - 1; i++) {
    sp[i][0] = lcp[i];
  }
  for (j = 1; j < 20; j++) {
    a = (1 << (j - 1));
    for (i = 0; i + (1 << j) - 1 < n - 1; i++) {
      sp[i][j] = min(sp[i][j - 1], sp[i + a][j - 1]);
    }
  }
}
signed main() {
  int a, b, i, j, q;
  cin >> n >> s >> q;
  s += "#";
  count_hp(s);
  n++;
  letter();
  find_sufmas();
  find_lcp();
  find_spars(n);
  build_lcp(1, n - 1, 1);
  find_tondem();
  build_tondem(1, n, 1);
  while (q--) {
    cin >> a >> b;
    cout << get_ans(a, b) << endl;
  }
}

### Prompt

Construct a cpp code solution to the problem outlined:

Ildar took a band (a thin strip of cloth) and colored it. Formally, the band has n cells, each of them is colored into one of 26 colors, so we can denote each color with one of the lowercase letters of English alphabet. 

Ildar decided to take some segment of the band [l, r] (1 ≤ l ≤ r ≤ n) he likes and cut it from the band. So he will create a new band that can be represented as a string t = s_l s_{l+1} … s_r.

After that Ildar will play the following game: he cuts the band t into some new bands and counts the number of different bands among them. Formally, Ildar chooses 1 ≤ k ≤ |t| indexes 1 ≤ i_1 < i_2 < … < i_k = |t| and cuts t to k bands-strings t_1 t_2 … t_{i_1}, t_{i_1 + 1} … t_{i_2}, …, {t_{i_{k-1} + 1}} … t_{i_k} and counts the number of different bands among them. He wants to know the minimal possible number of different bands he can get under the constraint that at least one band repeats at least two times. The result of the game is this number. If it is impossible to cut t in such a way, the result of the game is -1.

Unfortunately Ildar hasn't yet decided which segment he likes, but he has q segments-candidates [l_1, r_1], [l_2, r_2], ..., [l_q, r_q]. Your task is to calculate the result of the game for each of them.

Input

The first line contains one integer n (1 ≤ n ≤ 200 000) — the length of the band Ildar has.

The second line contains a string s consisting of n lowercase English letters — the band Ildar has.

The third line contains a single integer q (1 ≤ q ≤ 200 000) — the number of segments Ildar has chosen as candidates.

Each of the next q lines contains two integer integers l_i and r_i (1 ≤ l_i ≤ r_i ≤ n) denoting the ends of the i-th segment.

Output

Output q lines, where the i-th of them should contain the result of the game on the segment [l_i, r_i].

Example

Input

9
abcabcdce
7
1 6
4 7
5 9
6 9
1 9
3 6
4 4


Output

1
-1
4
3
2
2
-1

Note

Consider the first example.

If Ildar chooses the segment [1, 6], he cuts a string t = abcabc. If he cuts t into two bands abc and abc, the band abc repeats two times and the number of different tapes is 1. So, the result of this game is 1.

If Ildar chooses the segment [4, 7], he cuts a string t = abcd. It is impossible to cut this band in such a way that there is at least one band repeating at least two times. So, the result of this game is -1.

If Ildar chooses the segment [3, 6], he cuts a string t = cabc. If he cuts t into three bands c, ab and c, the band c repeats two times and the number of different bands is 2. So, the result of this game is 2.

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int n;
string s;
int asd[maxn];
int asdf[maxn];
int lcp[maxn];
int rig[maxn];
int lef[maxn];
int letters[maxn][26];
int tree[4 * maxn];
int tree_lcp[4 * maxn];
int spars[maxn][30];
int pos[maxn];
int suf[maxn];
int c[maxn];
int last[26];
int sp[maxn][20];
int st[maxn];
pair<pair<int, int>, int> t[maxn];
struct der {
  int x;
  int type;
  int len;
};
vector<der> vec, ve;
multiset<int> curr;
long long h[maxn];
long long p[maxn];
long long base = 200033;
long long h1[maxn];
long long p1[maxn];
long long base1 = 200017;
void fast() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
}
void letter() {
  int i, j, a;
  for (i = 0; i < n - 1; i++) {
    letters[i][s[i] - 'a'] = 1;
  }
  for (i = 1; i < n - 1; i++) {
    for (j = 0; j < 26; j++) {
      letters[i][j] += letters[i - 1][j];
    }
  }
  for (i = 0; i < 26; i++) {
    last[i] = -1;
  }
  for (i = 0; i < n - 1; i++) {
    a = s[i] - 'a';
    asdf[i] = last[a];
    last[a] = i;
  }
  for (i = 0; i < 26; i++) {
    last[i] = n;
  }
  for (i = n - 2; i >= 0; i--) {
    a = s[i] - 'a';
    asd[i] = last[a];
    last[a] = i;
  }
}
void find_sufmas() {
  int i, j;
  for (i = 0; i < n; i++) c[i] = s[i] - 'a' + 1;
  c[n - 1] = -300;
  for (i = 1; i < n; i <<= 1) {
    for (j = 0; j < n; j++) {
      t[j] = {{c[j], c[(i + j) % n]}, j};
    }
    sort(t, t + n);
    int cnt = 0;
    for (j = 0; j < n; j++) {
      if (j && t[j].first != t[j - 1].first) cnt++;
      c[t[j].second] = cnt;
    }
  }
  for (i = 0; i < n; i++) {
    suf[c[i]] = i;
  }
}
void find_lcp() {
  int i;
  for (i = 0; i < n; i++) {
    pos[suf[i]] = i;
  }
  int k = 0;
  for (i = 0; i < n; i++) {
    if (pos[i] == n - 1) {
      k = 0;
      continue;
    }
    int j = suf[pos[i] + 1];
    while (i + k < n && j + k < n && s[i + k] == s[j + k]) k++;
    lcp[pos[i]] = k;
    if (k) k--;
  }
}
void build_lcp(int l, int r, int v) {
  if (l == r) {
    tree_lcp[v] = lcp[r - 1];
  } else {
    int m = (r + l) / 2;
    build_lcp(l, m, v * 2);
    build_lcp(m + 1, r, v * 2 + 1);
    tree_lcp[v] = min(tree_lcp[v * 2], tree_lcp[v * 2 + 1]);
  }
}
int get_get_lcp(int l, int r, int tl, int tr, int v) {
  if (l == tl && r == tr) {
    return tree_lcp[v];
  } else {
    int m = (r + l) / 2;
    if (tr <= m) {
      return get_get_lcp(l, m, tl, tr, v * 2);
    } else if (tl > m) {
      return get_get_lcp(m + 1, r, tl, tr, v * 2 + 1);
    } else {
      return min(get_get_lcp(l, m, tl, m, v * 2),
                 get_get_lcp(m + 1, r, m + 1, tr, v * 2 + 1));
    }
  }
}
int get_lcp(int a, int b) {
  if (pos[a] > pos[b]) swap(a, b);
  a = pos[a], b = pos[b] - 1;
  int len = b - a + 1;
  len = st[len];
  return min(sp[a][len], sp[b - (1 << len) + 1][len]);
}
bool check(long long len, long long a, long long b) {
  if (a > b) swap(a, b);
  long long l = a - len + 1;
  long long r = b - len + 1;
  long long h0 = h[a];
  if (l) h0 -= h[l - 1] * p[len];
  long long h2 = h[b];
  if (r) h2 -= h[r - 1] * p[len];
  long long h3 = h1[a];
  if (l) h3 -= h1[l - 1] * p1[len];
  long long h4 = h1[b];
  if (r) h4 -= h1[r - 1] * p1[len];
  return h0 == h2 && h3 == h4;
}
int get_rlcp(int a, int b) {
  long long l = 0, r = min(a, b) + 2;
  while (r - l > 1) {
    long long m = (r + l) / 2;
    if (check(m, a, b)) {
      l = m;
    } else {
      r = m;
    }
  }
  return l;
}
void fun_tondem(int l, int r) {
  if (r == l) return;
  if (l + 1 == r) {
    if (s[l] == s[r]) {
      rig[l] = r;
      lef[r] = l;
    }
    return;
  }
  if (l + 2 == r) {
    if (s[l] == s[l + 1]) {
      rig[l] = l + 1;
      lef[l + 1] = l;
    }
    if (s[l + 1] == s[r]) {
      rig[l + 1] = r;
      lef[r] = l + 1;
    }
    return;
  }
  int mid = (l + r) / 2;
  int i, j;
  for (i = l; i <= mid; i++) {
    if (get_lcp(i, mid + 1) + i - 1 >= mid) {
      int a = i + (mid - i + 1) * 2 - 1;
      rig[i] = min(rig[i], a);
      lef[a] = max(lef[a], i);
    }
  }
  for (i = l + 1; i <= mid - 1; i++) {
    int len = mid - i + 1;
    int tl = max(1, len - get_lcp(i, mid + 1));
    int tr = min({len - 1, get_rlcp(mid, i - 1), i - l});
    if (tl <= tr) {
      vec.push_back({i - tr, 0, len});
      vec.push_back({i - tl + 1, 1, len});
      ve.push_back({i - tr + 2 * len - 1 - 1, 0, len});
      ve.push_back({i - tl + 2 * len - 1, 1, len});
    }
  }
  for (i = mid + 2; i < r; i++) {
    int len = i - (mid + 1) + 1;
    int tl = max({1, len - get_lcp(mid + 1, i + 1), len - r + i});
    int tr = min(len - 1, get_rlcp(mid, i));
    if (tl <= tr) {
      vec.push_back({mid - tr + 1, 0, len});
      vec.push_back({mid - tl + 1 + 1, 1, len});
      ve.push_back({mid - tr + 1 + 2 * len - 1 - 1, 0, len});
      ve.push_back({mid - tl + 1 + 2 * len - 1, 1, len});
    }
  }
  fun_tondem(l, mid);
  fun_tondem(mid + 1, r);
}
bool cmp(der a, der b) {
  if (a.x == b.x) {
    return a.type < b.type;
  }
  return a.x < b.x;
}
bool cmp1(der a, der b) {
  if (a.x == b.x) {
    return a.type > b.type;
  }
  return a.x > b.x;
}
void find_tondem() {
  int i, j;
  for (i = 0; i < n; i++) {
    rig[i] = n + 3;
    lef[i] = -1;
  }
  fun_tondem(0, n - 1);
  sort(vec.begin(), vec.end(), cmp);
  j = 0;
  for (i = 0; i < n; i++) {
    while (j < vec.size() && vec[j].x == i) {
      if (vec[j].type == 0) {
        curr.insert(vec[j].len);
      } else {
        curr.erase(curr.find(vec[j].len));
      }
      j++;
    }
    if (curr.size()) {
      rig[i] = min(rig[i], i + *curr.begin() * 2 - 1);
    }
  }
  sort(ve.begin(), ve.end(), cmp1);
  curr.clear();
  j = 0;
  for (i = n - 1; i >= 0; i--) {
    while (j < ve.size() && ve[j].x == i) {
      if (ve[j].type == 1) {
        curr.insert(ve[j].len);
      } else {
        curr.erase(curr.find(ve[j].len));
      }
      j++;
    }
    if (curr.size()) {
      lef[i] = max(lef[i], i - *curr.begin() * 2 + 1);
    }
  }
}
bool chk_letters(int l, int r) {
  for (int i = 0; i < 26; i++) {
    int a = letters[r][i];
    if (l) a -= letters[l - 1][i];
    if (a > 1) return true;
  }
  return false;
}
bool chk_1(int l, int r) {
  int n = r - l + 1;
  int nn = n;
  for (int i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      while (n % i == 0) {
        n /= i;
      }
      if (nn / i == nn) continue;
      if (get_lcp(l, l + nn / i) + l + nn / i - 1 >= r) {
        return true;
      }
    }
  }
  if (nn / n != nn) {
    if (get_lcp(l, l + nn / n) + l + nn / n - 1 >= r) {
      return true;
    }
  }
  return false;
}
bool find_border(int l, int r) {
  int sq = 500;
  int a, b;
  for (int i = l; (i - l + 1) * 2 <= r - l + 1 && i <= sq + l; i++) {
    a = l, b = r - (i - l);
    if (get_lcp(a, b) >= i - l + 1) {
      return true;
    }
  }
  a = pos[l];
  for (int i = max(0, a - sq); i <= min(n - 1, a + sq); i++) {
    b = suf[i];
    if (b > l && b <= r && (r - b + 1) * 2 <= r - l + 1 &&
        l + (r - b + 1) - 1 < b) {
      if (get_lcp(l, b) >= r - b + 1) {
        return true;
      }
    }
  }
  return false;
}
bool chk_2(int a, int b) {
  if (rig[a] <= b || lef[b] >= a) {
    return true;
  }
  return find_border(a, b);
}
void build_tondem(int l, int r, int v) {
  if (l == r) {
    tree[v] = rig[r - 1];
  } else {
    int m = (r + l) / 2;
    build_tondem(l, m, v * 2);
    build_tondem(m + 1, r, v * 2 + 1);
    tree[v] = min(tree[v * 2], tree[v * 2 + 1]);
  }
}
int get_tondem(int l, int r, int tl, int tr, int v) {
  if (l == tl && r == tr) {
    return tree[v];
  } else {
    int m = (r + l) / 2;
    if (tr <= m) {
      return get_tondem(l, m, tl, tr, v * 2);
    } else if (tl > m) {
      return get_tondem(m + 1, r, tl, tr, v * 2 + 1);
    } else {
      return min(get_tondem(l, m, tl, m, v * 2),
                 get_tondem(m + 1, r, m + 1, tr, v * 2 + 1));
    }
  }
}
int min_tondem(int l, int r) {
  l++, r++;
  return get_tondem(1, n, l, r, 1);
}
bool chk_3(int a, int b) {
  if (asd[a] <= b || asdf[b] >= a) {
    return true;
  }
  return (min_tondem(a, b) <= b);
}
int get_ans(int a, int b) {
  a--, b--;
  if (!chk_letters(a, b)) {
    return -1;
  }
  if (chk_1(a, b)) {
    return 1;
  }
  if (chk_2(a, b)) {
    return 2;
  }
  if (chk_3(a, b)) {
    return 3;
  }
  return 4;
}
void count_hp(string s) {
  int n = s.size();
  h[0] = s[0] - 'a' + 1;
  h1[0] = s[0] - 'a' + 1;
  for (int i = 1; i < n; i++) {
    h[i] = h[i - 1] * base + s[i] - 'a' + 1;
    h1[i] = h1[i - 1] * base1 + s[i] - 'a' + 1;
  }
  p[0] = 1;
  p1[0] = 1;
  for (int i = 1; i <= n; i++) {
    p[i] = p[i - 1] * base;
    p1[i] = p1[i - 1] * base1;
  }
}
void find_spars(int n) {
  int a = 1;
  int b = 0;
  int i, j;
  st[1] = 0;
  for (i = 2; i <= n - 1; i++) {
    st[i] = st[i / 2] + 1;
  }
  for (i = 0; i < n - 1; i++) {
    sp[i][0] = lcp[i];
  }
  for (j = 1; j < 20; j++) {
    a = (1 << (j - 1));
    for (i = 0; i + (1 << j) - 1 < n - 1; i++) {
      sp[i][j] = min(sp[i][j - 1], sp[i + a][j - 1]);
    }
  }
}
signed main() {
  int a, b, i, j, q;
  cin >> n >> s >> q;
  s += "#";
  count_hp(s);
  n++;
  letter();
  find_sufmas();
  find_lcp();
  find_spars(n);
  build_lcp(1, n - 1, 1);
  find_tondem();
  build_tondem(1, n, 1);
  while (q--) {
    cin >> a >> b;
    cout << get_ans(a, b) << endl;
  }
}

```