#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
struct ZAlgo {
  string s;
  int n;
  vector<int> z;
  void init(int _n) {
    n = _n;
    s = string(n, '?');
    z = vector<int>(n, -1);
  }
  void calc() {
    int l = 0, r = 0;
    for (int i = (1); i < (n); ++i) {
      if (i < r) {
        int k = i - l;
        if (z[k] < r - i) {
          z[i] = z[k];
          continue;
        } else
          l = i;
      } else
        l = r = i;
      while (r < n && s[r] == s[r - l]) ++r;
      z[i] = r - l;
    }
  }
};
struct RepeatRun {
  int l, r, len;
  RepeatRun(int l, int r, int len) : l(l), r(r), len(len) {}
};
struct RepeatFinder {
  char *s;
  int n;
  ZAlgo ba, abrev;
  vector<RepeatRun> runs;
  void rec(int l, int r) {
    if (l == r) return;
    int m = l + (r - l) / 2;
    rec(l, m);
    rec(m + 1, r);
    ba.n = 0;
    for (int i = (m + 1); i <= (r); ++i) ba.s[ba.n++] = s[i];
    ba.s[ba.n++] = '#';
    for (int i = (l); i <= (m); ++i) ba.s[ba.n++] = s[i];
    abrev.n = 0;
    for (int i = m; i >= l; --i) abrev.s[abrev.n++] = s[i];
    abrev.s[abrev.n++] = '#';
    for (int i = r; i >= m + 1; --i) abrev.s[abrev.n++] = s[i];
    ba.calc();
    abrev.calc();
    for (int i = (l); i <= (m); ++i) {
      int k = m - i + 1, k1 = abrev.z[k], k2 = ba.z[r - m + 1 + i - l];
      if (k1 + k2 >= k && k2 >= 1)
        runs.push_back(RepeatRun(i - min(k - 1, k1), i - (k - k2), k));
    }
    for (int i = (m + 2); i <= (r); ++i) {
      int k = i - m, k1 = ba.z[k], k2 = abrev.z[m - l + 1 + 1 + r - i];
      if (k1 + k2 >= k && k2 >= 1 && k1 >= 1)
        runs.push_back(
            RepeatRun(m + 1 - min(k - 1, k2), m + 1 - max(k - k1, 1), k));
    }
  }
  void init(char *_s) {
    s = _s;
    n = strlen(s);
    ba.init(n + 1);
    abrev.init(n + 1);
  }
  void calcruns() {
    runs.clear();
    rec(0, n - 1);
  }
  vector<int> calcminstart() {
    vector<vector<int>> e(n + 1);
    for (int i = (0); i < (((int)(runs).size())); ++i)
      e[runs[i].l].push_back(runs[i].len),
          e[runs[i].r + 1].push_back(-runs[i].len);
    multiset<int> have;
    vector<int> ret(n);
    for (int i = (0); i < (n); ++i) {
      for (int j = (0); j < (((int)(e[i]).size())); ++j) {
        int x = e[i][j];
        if (x > 0)
          have.insert(x);
        else
          have.erase(have.find(-x));
      }
      ret[i] = ((int)(have).size()) == 0 ? 0 : *have.begin();
    }
    return ret;
  }
  vector<int> calcminend() {
    vector<vector<int>> e(n + 1);
    for (int i = (0); i < (((int)(runs).size())); ++i)
      e[runs[i].l + 2 * runs[i].len - 1].push_back(runs[i].len),
          e[runs[i].r + 2 * runs[i].len].push_back(-runs[i].len);
    multiset<int> have;
    vector<int> ret(n);
    for (int i = (0); i < (n); ++i) {
      for (int j = (0); j < (((int)(e[i]).size())); ++j) {
        int x = e[i][j];
        if (x > 0)
          have.insert(x);
        else
          have.erase(have.find(-x));
      }
      ret[i] = ((int)(have).size()) == 0 ? 0 : *have.begin();
    }
    return ret;
  }
};
struct RMQ {
  int *a;
  int n;
  void init(int *_a, int _n) {
    a = _a;
    n = _n;
  }
  vector<int> lg;
  vector<vector<int>> rmq;
  void calc() {
    lg = vector<int>(n + 1);
    lg[1] = 0;
    for (int i = (1); i <= (n); ++i) {
      lg[i] = lg[i - 1];
      while ((2 << lg[i]) <= i) ++lg[i];
    }
    rmq = vector<vector<int>>(n, vector<int>(lg[n] + 1));
    for (int i = (0); i < (n); ++i) rmq[i][0] = a[i];
    for (int k = (0); k < (lg[n]); ++k)
      for (int i = (0); i < (n); ++i)
        if (i + (1 << k) < n)
          rmq[i][k + 1] = min(rmq[i][k], rmq[i + (1 << k)][k]);
        else
          rmq[i][k + 1] = rmq[i][k];
  }
  int query(int l, int r) {
    int k = lg[r - l + 1];
    return min(rmq[l][k], rmq[r - (1 << k) + 1][k]);
  }
};
struct SuffixArray {
  char *s;
  int n;
  void init(char *_s, bool cyclic) {
    s = _s;
    n = strlen(s) + (cyclic ? 0 : 1);
  }
  vector<int> sa, id, cnt, sa2, oid;
  int nid;
  void calcsuffixarray() {
    sa = id = sa2 = oid = vector<int>(n);
    nid = 256;
    cnt = vector<int>(max(n, nid), 0);
    for (int i = (0); i < (n); ++i) oid[i] = (int)s[i];
    for (int i = (0); i < (n); ++i) ++cnt[oid[i]];
    for (int i = (1); i < (nid); ++i) cnt[i] += cnt[i - 1];
    for (int i = (0); i < (n); ++i) sa[--cnt[oid[i]]] = i;
    nid = 0;
    for (int i = (0); i < (n); ++i)
      if (i == 0 || oid[sa[i]] != oid[sa[i - 1]])
        id[sa[i]] = nid++;
      else
        id[sa[i]] = id[sa[i - 1]];
    for (int step = 0; (1 << step) < n; ++step) {
      for (int i = (0); i < (n); ++i) {
        oid[i] = id[i], sa2[i] = sa[i] - (1 << step);
        if (sa2[i] < 0) sa2[i] += n;
      }
      for (int i = (0); i < (nid); ++i) cnt[i] = 0;
      for (int i = (0); i < (n); ++i) ++cnt[oid[sa2[i]]];
      for (int i = (1); i < (nid); ++i) cnt[i] += cnt[i - 1];
      for (int i = n - 1; i >= 0; --i) sa[--cnt[oid[sa2[i]]]] = sa2[i];
      nid = 0;
      for (int i = (0); i < (n); ++i)
        if (i == 0 || oid[sa[i]] != oid[sa[i - 1]] ||
            oid[(sa[i] + (1 << step)) % n] !=
                oid[(sa[i - 1] + (1 << step)) % n])
          id[sa[i]] = nid++;
        else
          id[sa[i]] = id[sa[i - 1]];
    }
  }
  vector<int> pos, lcp;
  void calcadjacentlcp() {
    pos = vector<int>(n);
    for (int i = (0); i < (n); ++i) pos[sa[i]] = i;
    lcp = vector<int>(n - 1);
    int k = 0;
    for (int i = (0); i < (n); ++i)
      if (pos[i] != n - 1) {
        while (i + k < n && sa[pos[i] + 1] + k < n &&
               s[i + k] == s[sa[pos[i] + 1] + k])
          ++k;
        lcp[pos[i]] = k;
        k = max(0, k - 1);
      }
  }
  RMQ rmq;
  void preparegenerallcp() {
    rmq.init(lcp.data(), n - 1);
    rmq.calc();
  }
  int querylcp(int l, int r) {
    l = pos[l], r = pos[r];
    if (l > r) swap(l, r);
    if (l == r) return n - l;
    return rmq.query(l, r - 1);
  }
};
const int MAXLEN = 200000;
const int MAXQ = 200000;
const int ALPH = 26;
int slen;
char s[MAXLEN + 1];
int nq;
int ql[MAXQ], qr[MAXQ], qans[MAXQ];
int charsum[MAXLEN + 1][ALPH];
RepeatFinder repeatfinder;
int firstrepeatends[MAXLEN];
int lastrepeatstarts[MAXLEN];
SuffixArray suffixarray;
int pmn[MAXLEN + 1];
RMQ nextrepeatends;
int sqrtslen;
void precalc() {
  for (int k = (0); k < (ALPH); ++k) charsum[0][k] = 0;
  for (int i = (0); i < (slen); ++i)
    for (int k = (0); k < (ALPH); ++k)
      charsum[i + 1][k] = charsum[i][k] + (s[i] == 'a' + k ? 1 : 0);
  repeatfinder.init(s);
  repeatfinder.calcruns();
  vector<int> minstart = repeatfinder.calcminstart(),
              minend = repeatfinder.calcminend();
  for (int i = (0); i < (slen); ++i)
    firstrepeatends[i] = minstart[i] == 0 ? slen : i + 2 * minstart[i] - 1;
  for (int i = (0); i < (slen); ++i)
    lastrepeatstarts[i] = minend[i] == 0 ? -1 : i - 2 * minend[i] + 1;
  nextrepeatends.init(firstrepeatends, slen);
  nextrepeatends.calc();
  suffixarray.init(s, false);
  suffixarray.calcsuffixarray();
  suffixarray.calcadjacentlcp();
  suffixarray.preparegenerallcp();
  memset(pmn, -1, sizeof(pmn));
  for (int i = (2); i <= (MAXLEN); ++i)
    if (pmn[i] == -1)
      for (int j = i; j <= MAXLEN; j += i)
        if (pmn[j] == -1) pmn[j] = i;
  sqrtslen = 1;
  while (sqrtslen * sqrtslen <= slen) ++sqrtslen;
}
int countchar(int l, int r, char c) {
  return charsum[r + 1][c - 'a'] - charsum[l][c - 'a'];
}
bool impossible(int l, int r) {
  for (char c = 'a'; c <= 'z'; ++c)
    if (countchar(l, r, c) >= 2) return false;
  return true;
}
bool periodic(int l, int r) {
  int len = r - l + 1, x = len;
  while (x != 1) {
    int p = pmn[x], repcnt = p, replen = len / repcnt;
    if (suffixarray.querylcp(l, l + replen) >= len - replen) return true;
    while (x % p == 0) x /= p;
  }
  return false;
}
bool startswithrepeat(int l, int r) { return firstrepeatends[l] <= r; }
bool endswithrepeat(int l, int r) { return lastrepeatstarts[r] >= l; }
bool hasborder(int l, int r) {
  for (int len = (1); len < (sqrtslen); ++len)
    if (len >= r - l + 1)
      return false;
    else if (suffixarray.querylcp(l, r - len + 1) >= len)
      return true;
  int lim = (slen - 1) / sqrtslen, lo = max(0, suffixarray.pos[l] - lim),
      hi = min(slen, suffixarray.pos[l] + lim);
  for (int idx = (lo); idx <= (hi); ++idx) {
    int i = suffixarray.sa[idx];
    if (i > l && i <= r && suffixarray.querylcp(l, i) >= r - i + 1) return true;
  }
  return false;
}
bool containschar(int l, int r, char c) { return countchar(l, r, c) >= 1; }
bool containsrepeat(int l, int r) { return nextrepeatends.query(l, r) <= r; }
int calc(int l, int r) {
  if (impossible(l, r)) return -1;
  if (periodic(l, r)) return 1;
  if (startswithrepeat(l, r) || endswithrepeat(l, r) || hasborder(l, r))
    return 2;
  if (containschar(l + 1, r, s[l]) || containschar(l, r - 1, s[r]) ||
      containsrepeat(l, r))
    return 3;
  return 4;
}
void solve() {
  precalc();
  for (int i = (0); i < (nq); ++i) qans[i] = calc(ql[i], qr[i]);
}
void run() {
  scanf("%d", &slen);
  scanf("%s", s);
  scanf("%d", &nq);
  for (int i = (0); i < (nq); ++i)
    scanf("%d%d", &ql[i], &qr[i]), --ql[i], --qr[i];
  solve();
  for (int i = (0); i < (nq); ++i) printf("%d\n", qans[i]);
}
int main() {
  run();
  return 0;
}
