#include <bits/stdc++.h>
using namespace std;
const int INF = 100000005;
const int p = 31;
const int mod = (1 << 8) - 1;
char s[200005];
const int siz = 5;
struct node {
 public:
  int c[5][5];
  void out() {
    for (int i = 0; i < siz; i++) {
      for (int j = 0; j < siz; j++) {
        printf("%8d ", c[i][j]);
      }
      puts("");
    }
    puts("");
  }
  node operator^(long long m) {
    int i;
    node tmp, a = (*this);
    memset(tmp.c, 0, sizeof(tmp.c));
    for (i = 1; i <= siz; i++) tmp.c[i][i] = 1;
    while (m) {
      if (m & 1) {
        tmp = (tmp * a);
      }
      a = (a * a);
      m >>= 1;
    }
    return tmp;
  }
  node operator*(node& b) {
    node tmp;
    int i, j, k;
    for (i = 0; i < siz; i++)
      for (j = i; j < siz; j++) {
        tmp.c[i][j] = INF;
        for (k = i; k <= j; k++)
          tmp.c[i][j] = min(tmp.c[i][j], c[i][k] + b.c[k][j]);
        if (tmp.c[i][j] > INF) tmp.c[i][j] = INF;
      }
    return tmp;
  }
  node operator+(node& b) {
    node tmp;
    int i, j;
    for (i = 1; i <= siz; i++)
      for (j = 1; j <= siz; j++) {
        tmp.c[i][j] = (c[i][j] + b.c[i][j]) % mod;
      }
    return tmp;
  }
  void init() {
    for (int i = 0; i < siz; i++)
      for (int j = i; j < siz; j++) c[i][j] = INF;
  }
};
struct Tree {
  node a;
  int l, r;
} tr[200005 << 2];
int n;
void upd(int x, int num) {
  int i, j;
  for (i = 0; i < siz; i++) tr[x].a.c[i][i] = 0;
  if (num == 6) tr[x].a.c[3][3] = tr[x].a.c[4][4] = 1;
  if (num == 2) tr[x].a.c[0][1] = 0, tr[x].a.c[0][0] = 1;
  if (num == 0) tr[x].a.c[1][2] = 0, tr[x].a.c[1][1] = 1;
  if (num == 1) tr[x].a.c[2][3] = 0, tr[x].a.c[2][2] = 1;
  if (num == 7) tr[x].a.c[3][4] = 0, tr[x].a.c[3][3] = 1;
}
void pushup(int x) { tr[x].a = tr[x << 1].a * tr[x << 1 | 1].a; }
void build(int l, int r, int x) {
  tr[x].l = l, tr[x].r = r;
  tr[x].a.init();
  if (l == r) {
    upd(x, s[l] - '0');
    return;
  }
  int mid = (l + r) / 2;
  build(l, mid, x << 1);
  build(mid + 1, r, x << 1 | 1);
  pushup(x);
}
node query(int L, int R, int x) {
  int l = tr[x].l, r = tr[x].r;
  if (l == L && R == r) {
    return tr[x].a;
  }
  int mid = (l + r) / 2;
  if (R <= mid)
    return query(L, R, x << 1);
  else if (L > mid)
    return query(L, R, x << 1 | 1);
  else {
    node nw, n1, n2;
    nw.init();
    n1 = query(L, mid, x << 1);
    n2 = query(mid + 1, R, x << 1 | 1);
    nw = n1 * n2;
    return nw;
  }
}
int main() {
  int l, r, i, j, m;
  scanf("%d %d", &n, &m);
  scanf("%s", s + 1);
  build(1, n, 1);
  while (m--) {
    scanf("%d %d", &l, &r);
    node nw;
    nw = query(l, r, 1);
    if (nw.c[0][4] == INF)
      printf("-1\n");
    else
      printf("%d\n", nw.c[0][4]);
  }
}
