#include <bits/stdc++.h>
using namespace std;
void In() { freopen("in.in", "r", stdin); }
void Out() { freopen("out.out", "w", stdout); }
const int N = 2e5 + 10;
const int M = 3e5 + 10;
const int Mbit = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
char s[N];
struct node {
  int a[5][5];
  node operator+(node x) {
    node ans;
    for (int i = 0; i < 5; i++)
      for (int j = 0; j < 5; j++) {
        ans.a[i][j] = N;
        for (int k = 0; k < 5; k++) {
          ans.a[i][j] = min(ans.a[i][j], a[i][k] + x.a[k][j]);
        }
      }
    return ans;
  }
} tree[N << 2];
void build(int l, int r, int rt) {
  if (l == r) {
    for (int i = 0; i < 5; i++)
      for (int j = 0; j < 5; j++) tree[rt].a[i][j] = (i == j) ? 0 : N;
    if (s[l] == '2') tree[rt].a[0][1] = 0, tree[rt].a[0][0] = 1;
    if (s[l] == '0') tree[rt].a[1][2] = 0, tree[rt].a[1][1] = 1;
    if (s[l] == '1') tree[rt].a[2][3] = 0, tree[rt].a[2][2] = 1;
    if (s[l] == '7') tree[rt].a[3][4] = 0, tree[rt].a[3][3] = 1;
    if (s[l] == '6') tree[rt].a[3][3] = 1, tree[rt].a[4][4] = 1;
    return;
  }
  int mid = l + r >> 1;
  build(l, mid, (rt << 1));
  build(mid + 1, r, (rt << 1 | 1));
  tree[rt] = tree[(rt << 1)] + tree[(rt << 1 | 1)];
}
node query(int l, int r, int rt, int L, int R) {
  if (L <= l && r <= R) return tree[rt];
  int mid = l + r >> 1;
  if (R <= mid)
    return query(l, mid, (rt << 1), L, R);
  else if (L > mid)
    return query(mid + 1, r, (rt << 1 | 1), L, R);
  return query(l, mid, (rt << 1), L, R) +
         query(mid + 1, r, (rt << 1 | 1), L, R);
}
int main() {
  int n, q;
  while (~scanf("%d%d", &n, &q)) {
    scanf("%s", s + 1);
    build(1, n, 1);
    while (q--) {
      int l, r;
      scanf("%d%d", &l, &r);
      int ans = query(1, n, 1, l, r).a[0][4];
      if (ans == N) ans = -1;
      printf("%d\n", ans);
    }
  }
  return 0;
}
