#include <bits/stdc++.h>

#define pb push_back
#define rep(i, n) for (int i = 1 ; i <= (n) ; i++)
#define per(i, n) for (int i = (n) ; i >= 1 ; i--)
#define repi(n) for (int i = 1; i <= (n) ; i++)
#define mabs(n) ((n) > 0 ? (n) : (-n))
#define sqr(n) ((n) * (n))
#define print(V) for (auto v: V) printf("%d ",v)
using namespace std;
typedef pair<int, int> mp;
typedef long long LL ;
const int maxn = 1e3 + 5;
const int maxm = 1e6 + 500;

unordered_map< LL, bool> container;
int dx[] = {0, -1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {0, -1, 0, 1, -1, 1, -1, 0, 1};
char str[maxn][maxn];
int id[maxn][maxn], tot, S, T;
int p1[maxm], p2[maxm], n, m, q;

int stk[maxn], top, x_[maxn], y_[maxn];
int find1(int u) {return p1[u] ? p1[u] = find1(p1[u]) : u;}
int find2(int u) {return p2[u] ? p2[u] = find2(p2[u]) : u;}
void merge1(int u, int v) {u = find1(u); v = find1(v); u != v ? p1[u] = v : 0;}
void merge2(int u, int v) {u = find2(u); v = find2(v); if (u < v) swap(u, v); u != v ? (stk[++top] = u, p2[u] = v) : 0;}
bool inG(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m;}
void insert(int x, int y) {container[(LL)x * 1000000ll + y] = true;}
bool query(int x, int y) {return container[(LL)x * 1000000ll + y];}

bool check(int x, int y)
{
	if (!inG(x, y)) return false;
	if (x == 1 && y == 1) return false;
	if (x == n && y == m) return false;

	bool conS = false, conT = false;
	rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (find2(find1(id[nx][ny])) == find2(find1(S))) conS = true;
		if (find2(find1(id[nx][ny])) == find2(find1(T))) conT = true;
	}
	return conS && conT;
}
int main()
{
	#ifdef FILE_TEST
		freopen("grid.in", "r", stdin);
	#endif

	scanf("%d %d %d", &n, &m, &q);
	repi(n) scanf("%s", str[i] + 1);
	S = ++tot ; T = ++tot;
	repi(n) rep(j, m) id[i][j] = ++tot;

	repi(m) str[0][i] = '#', id[0][i] = T;
	repi(n) str[i][0] = '#', id[i][0] = S;
	repi(m) str[n + 1][i] = '#', id[n + 1][i] = S;
	repi(n) str[i][m + 1] = '#', id[i][m + 1] = T;
	id[0][0] = id[n + 1][m + 1] = ++tot;

	rep(x, n) rep(y, m) if (str[x][y] == '#') rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (str[nx][ny] == '#')
			merge1(id[x][y], id[nx][ny]);
	}

	rep(x, n) rep(y, m) rep(k1, 8)
	{
		int nx1 = x + dx[k1];
		int ny1 = y + dy[k1];
		if (str[nx1][ny1] != '#') continue;
		rep(k2, 8)
		{
			int nx2 = x + dx[k2];
			int ny2 = y + dy[k2];
			if (str[nx2][ny2] != '#') continue;
			int u = find1(str[nx1][ny1]);
			int v = find1(str[nx2][ny2]);
			if (u != v) insert(u, v);
		}
	}

	repi(q)
	{
		int r, x, y; bool OK = false;
		scanf("%d", &r);
		repi(r) scanf("%d %d", &x_[i], &y_[i]);
		repi(r) str[x_[i]][y_[i]] = '#';
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			if (str[nx][ny] == '#')
				merge2(find1(id[x_[i]][y_[i]]), find1(id[nx][ny]));
		}
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			OK |= check(nx, ny);
		}

		OK |= find2(find1(T)) == find2(find1(S));
		rep(i, tot) if (find2(find1(i)) == find2(find1(S)))
		rep(j, tot) if (find2(find1(j)) == find2(find1(T)))
			OK |= query(i, j);
		repi(r) str[x_[i]][y_[i]] = '.';
		while (top) p2[ stk[top--]] = 0;
		printf("%s\n", OK ? "NO" : "YES");
		fflush(stdout);
	}
	return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define rep(i, n) for (int i = 1 ; i <= (n) ; i++)
#define per(i, n) for (int i = (n) ; i >= 1 ; i--)
#define repi(n) for (int i = 1; i <= (n) ; i++)
#define mabs(n) ((n) > 0 ? (n) : (-n))
#define sqr(n) ((n) * (n))
#define print(V) for (auto v: V) printf("%d ",v)
using namespace std;
typedef pair<int, int> mp;
typedef long long LL ;
const int maxn = 1e3 + 5;
const int maxm = 1e6 + 500;

map< mp, bool> container;
int dx[] = {0, -1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {0, -1, 0, 1, -1, 1, -1, 0, 1};
char str[maxn][maxn];
int id[maxn][maxn], tot, S, T;
int p1[maxm], p2[maxm], n, m, q;

int stk[maxn], top, x_[maxn], y_[maxn];
int find1(int u) {return p1[u] ? p1[u] = find1(p1[u]) : u;}
int find2(int u) {return p2[u] ? p2[u] = find2(p2[u]) : u;}
void merge1(int u, int v) {u = find1(u); v = find1(v); u != v ? p1[u] = v : 0;}
void merge2(int u, int v) {u = find2(u); v = find2(v); if (u < v) swap(u, v); u != v ? (stk[++top] = u, p2[u] = v) : 0;}
bool inG(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m;}
void insert(int x, int y) {container[mp(x, y)] = container[mp(y, x)] = true;}
bool query(int x, int y) {return container[mp(x, y)];}

bool check(int x, int y)
{
	if (!inG(x, y)) return false;
	if (x == 1 && y == 1) return false;
	if (x == n && y == m) return false;

	bool conS = false, conT = false;
	rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (find2(find1(id[nx][ny])) == find2(find1(S))) conS = true;
		if (find2(find1(id[nx][ny])) == find2(find1(T))) conT = true;
	}
	return conS && conT;
}
int main()
{
	#ifdef FILE_TEST
		freopen("grid.in", "r", stdin);
	#endif

	scanf("%d %d %d", &n, &m, &q);
	repi(n) scanf("%s", str[i] + 1);
	S = ++tot ; T = ++tot;
	repi(n) rep(j, m) id[i][j] = ++tot;

	repi(m) str[0][i] = '#', id[0][i] = T;
	repi(n) str[i][0] = '#', id[i][0] = S;
	repi(m) str[n + 1][i] = '#', id[n + 1][i] = S;
	repi(n) str[i][m + 1] = '#', id[i][m + 1] = T;
	id[0][0] = id[n + 1][m + 1] = ++tot;

	rep(x, n) rep(y, m) if (str[x][y] == '#') rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (str[nx][ny] == '#')
			merge1(id[x][y], id[nx][ny]);
	}

	rep(x, n) rep(y, m) rep(k1, 8)
	{
		int nx1 = x + dx[k1];
		int ny1 = y + dy[k1];
		if (str[nx1][ny1] != '#') continue;
		rep(k2, 8)
		{
			int nx2 = x + dx[k2];
			int ny2 = y + dy[k2];
			if (str[nx2][ny2] != '#') continue;
			int u = find1(str[nx1][ny1]);
			int v = find1(str[nx2][ny2]);
			if (u != v) insert(u, v);
		}
	}

	repi(q)
	{
		int r, x, y; bool OK = false;
		scanf("%d", &r);
		repi(r) scanf("%d %d", &x_[i], &y_[i]);
		repi(r) str[x_[i]][y_[i]] = '#';
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			if (str[nx][ny] == '#')
				merge2(find1(id[x_[i]][y_[i]]), find1(id[nx][ny]));
		}
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			OK |= check(nx, ny);
		}

		OK |= find2(find1(T)) == find2(find1(S));
		rep(i, tot) if (find2(find1(i)) == find2(find1(S)))
		rep(j, tot) if (find2(find1(j)) == find2(find1(T)))
			OK |= query(i, j);
		repi(r) str[x_[i]][y_[i]] = '.';
		while (top) p2[ stk[top--]] = 0;
		printf("%s\n", OK ? "NO" : "YES");
		fflush(stdout);
	}
	return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define rep(i, n) for (int i = 1 ; i <= (n) ; i++)
#define per(i, n) for (int i = (n) ; i >= 1 ; i--)
#define repi(n) for (int i = 1; i <= (n) ; i++)
#define mabs(n) ((n) > 0 ? (n) : (-n))
#define sqr(n) ((n) * (n))
#define print(V) for (auto v: V) printf("%d ",v)
using namespace std;
typedef pair<int, int> mp;
typedef long long LL ;
const int maxn = 1e3 + 5;
const int maxm = 1e6 + 500;

map< LL, bool> container;
int dx[] = {0, -1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {0, -1, 0, 1, -1, 1, -1, 0, 1};
char str[maxn][maxn];
int id[maxn][maxn], tot, S, T, hav[maxm];
int p1[maxm], p2[maxm], n, m, q;

int stk[maxm], top, x_[maxn], y_[maxn];
int find1(int u) {return p1[u] ? p1[u] = find1(p1[u]) : u;}
int find2(int u) {return p2[u] ? p2[u] = find2(p2[u]) : u;}
void merge1(int u, int v) {u = find1(u); v = find1(v); u != v ? p1[u] = v : 0;}
void merge2(int u, int v) {stk[++top] = u, stk[++top] = v; u = find2(u); v = find2(v); u != v ? p2[u] = v : 0;}
bool inG(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m;}
void insert(int x, int y) {hav[x] = hav[y] = true; container[(LL)x * 1000000ll + y] = true;}
bool query(int x, int y) {return container[(LL)x * 1000000ll + y];}

bool check(int x, int y)
{
	if (!inG(x, y)) return false;
	if (x == 1 && y == 1) return false;
	if (x == n && y == m) return false;

	bool conS = false, conT = false;
	rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (find2(id[nx][ny]) == find2(S)) conS = true;
		if (find2(id[nx][ny]) == find2(T)) conT = true;
	}
	return conS && conT;
}
int main()
{
	#ifdef FILE_TEST
		freopen("grid.in", "r", stdin);
	#endif

	scanf("%d %d %d", &n, &m, &q);
	repi(n) scanf("%s", str[i] + 1);
	S = ++tot ; T = ++tot;
	repi(n) rep(j, m) id[i][j] = ++tot;

	repi(m) str[0][i] = '#', id[0][i] = T;
	repi(n) str[i][0] = '#', id[i][0] = S;
	repi(m) str[n + 1][i] = '#', id[n + 1][i] = S;
	repi(n) str[i][m + 1] = '#', id[i][m + 1] = T;
	id[0][0] = ++tot; id[n + 1][m + 1] = ++tot;

	rep(x, n) rep(y, m) if (str[x][y] == '#') rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (str[nx][ny] == '#')
			merge1(id[x][y], id[nx][ny]);
	}
	S = find1(S); T = find1(T);
	for (int x = 0 ; x <= n + 1; x++ )
	for (int y = 0 ; y <= m + 1; y++ )
		id[x][y] = find1(id[x][y]);

	rep(x, n) rep(y, m) rep(k1, 8)
	{
		if (x == 1 && y == 1) continue;
		if (x == n && y == m) continue;
		int nx1 = x + dx[k1];
		int ny1 = y + dy[k1];
		if (str[nx1][ny1] != '#') continue;
		rep(k2, 8)
		{
			int nx2 = x + dx[k2];
			int ny2 = y + dy[k2];
			if (str[nx2][ny2] != '#') continue;
			int u = id[nx1][ny1];
			int v = id[nx2][ny2];
			if (u != v) insert(u, v);
		}
	}

	repi(q)
	{
		int r, x, y; bool OK = false;
		scanf("%d", &r);
		repi(r) scanf("%d %d", &x_[i], &y_[i]);
		repi(r) str[x_[i]][y_[i]] = '#';
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			if (str[nx][ny] == '#')
				merge2(id[x_[i]][y_[i]], id[nx][ny]);
		}
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			OK |= check(nx, ny);
		}

		OK |= find2(T) == find2(S);
		stk[++top] = S; stk[++top] = T;
		for (int i = 1; i <= top && !OK; i++) if (find2(stk[i]) == find2(S) && hav[stk[i]])
		for (int j = 1; j <= top && !OK; j++) if (find2(stk[j]) == find2(T) && hav[stk[j]])
			OK |= query(stk[i], stk[j]);
		repi(r) str[x_[i]][y_[i]] = '.';
		while (top) p2[ stk[top--]] = 0;
		printf("%s\n", OK ? "NO" : "YES");
		fflush(stdout);
	}
	return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define rep(i, n) for (int i = 1 ; i <= (n) ; i++)
#define per(i, n) for (int i = (n) ; i >= 1 ; i--)
#define repi(n) for (int i = 1; i <= (n) ; i++)
#define mabs(n) ((n) > 0 ? (n) : (-n))
#define sqr(n) ((n) * (n))
#define print(V) for (auto v: V) printf("%d ",v)
using namespace std;
typedef pair<int, int> mp;
typedef long long LL ;
const int maxn = 1e3 + 5;
const int maxm = 1e6 + 500;

unordered_map< LL, bool> container;
int dx[] = {0, -1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {0, -1, 0, 1, -1, 1, -1, 0, 1};
char str[maxn][maxn];
int id[maxn][maxn], tot, S, T;
int p1[maxm], p2[maxm], n, m, q;

int stk[maxn], top, x_[maxn], y_[maxn];
int find1(int u) {return p1[u] ? p1[u] = find1(p1[u]) : u;}
int find2(int u) {return p2[u] ? p2[u] = find2(p2[u]) : u;}
void merge1(int u, int v) {u = find1(u); v = find1(v); u != v ? p1[u] = v : 0;}
void merge2(int u, int v) {u = find2(u); v = find2(v); if (u > v) swap(u, v); u != v ? (stk[++top] = u, p2[u] = v) : 0;}
bool inG(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m;}
void insert(int x, int y) {container[(LL)x * 1000000ll + y] = true;}
bool query(int x, int y) {return container[(LL)x * 1000000ll + y];}

bool check(int x, int y)
{
	if (!inG(x, y)) return false;
	if (x == 1 && y == 1) return false;
	if (x == n && y == m) return false;

	bool conS = false, conT = false;
	rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (find2(id[nx][ny]) == find2(S)) conS = true;
		if (find2(id[nx][ny]) == find2(T)) conT = true;
	}
	return conS && conT;
}
int main()
{
	#ifdef FILE_TEST
		freopen("grid.in", "r", stdin);
	#endif

	scanf("%d %d %d", &n, &m, &q);
	repi(n) scanf("%s", str[i] + 1);
	S = ++tot ; T = ++tot;
	repi(n) rep(j, m) id[i][j] = ++tot;

	repi(m) str[0][i] = '#', id[0][i] = T;
	repi(n) str[i][0] = '#', id[i][0] = S;
	repi(m) str[n + 1][i] = '#', id[n + 1][i] = S;
	repi(n) str[i][m + 1] = '#', id[i][m + 1] = T;
	id[0][0] = ++tot; id[n + 1][m + 1] = ++tot;

	rep(x, n) rep(y, m) if (str[x][y] == '#') rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (str[nx][ny] == '#')
			merge1(id[x][y], id[nx][ny]);
	}
	S = find1(S); T = find1(T);
	for (int x = 0 ; x <= n + 1; x++ )
	for (int y = 0 ; y <= m + 1; y++ )
		id[x][y] = find1(id[x][y]);

	rep(x, n) rep(y, m) rep(k1, 8)
	{
		if (x == 1 && y == 1) continue;
		if (x == n && y == m) continue;
		int nx1 = x + dx[k1];
		int ny1 = y + dy[k1];
		if (str[nx1][ny1] != '#') continue;
		rep(k2, 8)
		{
			int nx2 = x + dx[k2];
			int ny2 = y + dy[k2];
			if (str[nx2][ny2] != '#') continue;
			int u = id[nx1][ny1];
			int v = id[nx2][ny2];
			if (u != v) insert(u, v);
		}
	}

	repi(q)
	{
		int r, x, y; bool OK = false;
		scanf("%d", &r);
		repi(r) scanf("%d %d", &x_[i], &y_[i]);
		repi(r) str[x_[i]][y_[i]] = '#';
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			if (str[nx][ny] == '#')
				merge2(id[x_[i]][y_[i]], id[nx][ny]);
		}
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			OK |= check(nx, ny);
		}

		OK |= find2(T) == find2(S);
		if (!OK)
		for (int i = 1; i <= tot ; i++) if (find2(i) == find2(S))
		for (int j = 1; j <= tot ; j++) if (find2(j) == find2(T))
			OK |= query(i, j);
		repi(r) str[x_[i]][y_[i]] = '.';
		while (top) p2[ stk[top--]] = 0;
		printf("%s\n", OK ? "NO" : "YES");
		fflush(stdout);
	}
	return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define rep(i, n) for (int i = 1 ; i <= (n) ; i++)
#define per(i, n) for (int i = (n) ; i >= 1 ; i--)
#define repi(n) for (int i = 1; i <= (n) ; i++)
#define mabs(n) ((n) > 0 ? (n) : (-n))
#define sqr(n) ((n) * (n))
#define print(V) for (auto v: V) printf("%d ",v)
using namespace std;
typedef pair<int, int> mp;
typedef long long LL ;
const int maxn = 1e3 + 5;
const int maxm = 1e6 + 500;

unordered_map< LL, bool> container;
int dx[] = {0, -1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {0, -1, 0, 1, -1, 1, -1, 0, 1};
char str[maxn][maxn];
int id[maxn][maxn], tot, S, T;
int p1[maxm], p2[maxm], n, m, q;

int stk[maxn], top, x_[maxn], y_[maxn];
int find1(int u) {return p1[u] ? p1[u] = find1(p1[u]) : u;}
int find2(int u) {return p2[u] ? p2[u] = find2(p2[u]) : u;}
void merge1(int u, int v) {u = find1(u); v = find1(v); u != v ? p1[u] = v : 0;}
void merge2(int u, int v) {u = find2(u); v = find2(v); u != v ? (stk[++top] = u, stk[++top] = v, p2[u] = v) : 0;}
bool inG(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m;}
void insert(int x, int y) {container[(LL)x * 1000000ll + y] = true;}
bool query(int x, int y) {return container[(LL)x * 1000000ll + y];}

bool check(int x, int y)
{
	if (!inG(x, y)) return false;
	if (x == 1 && y == 1) return false;
	if (x == n && y == m) return false;

	bool conS = false, conT = false;
	rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (find2(id[nx][ny]) == find2(S)) conS = true;
		if (find2(id[nx][ny]) == find2(T)) conT = true;
	}
	return conS && conT;
}
int main()
{
	#ifdef FILE_TEST
		freopen("grid.in", "r", stdin);
	#endif

	scanf("%d %d %d", &n, &m, &q);
	repi(n) scanf("%s", str[i] + 1);
	S = ++tot ; T = ++tot;
	repi(n) rep(j, m) id[i][j] = ++tot;

	repi(m) str[0][i] = '#', id[0][i] = T;
	repi(n) str[i][0] = '#', id[i][0] = S;
	repi(m) str[n + 1][i] = '#', id[n + 1][i] = S;
	repi(n) str[i][m + 1] = '#', id[i][m + 1] = T;
	id[0][0] = ++tot; id[n + 1][m + 1] = ++tot;

	rep(x, n) rep(y, m) if (str[x][y] == '#') rep(k, 8)
	{
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (str[nx][ny] == '#')
			merge1(id[x][y], id[nx][ny]);
	}
	S = find1(S); T = find1(T);
	for (int x = 0 ; x <= n + 1; x++ )
	for (int y = 0 ; y <= m + 1; y++ )
		id[x][y] = find1(id[x][y]);

	rep(x, n) rep(y, m) rep(k1, 8)
	{
		if (x == 1 && y == 1) continue;
		if (x == n && y == m) continue;
		int nx1 = x + dx[k1];
		int ny1 = y + dy[k1];
		if (str[nx1][ny1] != '#') continue;
		rep(k2, 8)
		{
			int nx2 = x + dx[k2];
			int ny2 = y + dy[k2];
			if (str[nx2][ny2] != '#') continue;
			int u = id[nx1][ny1];
			int v = id[nx2][ny2];
			if (u != v) insert(u, v);
		}
	}

	repi(q)
	{
		int r, x, y; bool OK = false;
		scanf("%d", &r);
		repi(r) scanf("%d %d", &x_[i], &y_[i]);
		repi(r) str[x_[i]][y_[i]] = '#';
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			if (str[nx][ny] == '#')
				merge2(id[x_[i]][y_[i]], id[nx][ny]);
		}
		repi(r) rep(k, 8)
		{
			int nx = x_[i] + dx[k];
			int ny = y_[i] + dy[k];
			OK |= check(nx, ny);
		}

		OK |= find2(T) == find2(S);
		if (!OK)
		for (int i = 1; i <= tot ; i++) if (find2(i) == find2(S))
		for (int j = 1; j <= tot ; j++) if (find2(j) == find2(T))
			OK |= query(i, j);
		repi(r) str[x_[i]][y_[i]] = '.';
		while (top) p2[ stk[top--]] = 0;
		printf("%s\n", OK ? "NO" : "YES");
		fflush(stdout);
	}
	return 0;
}


#include<bits/stdc++.h>
#define For(i,j,k) for (int i=(j);i<=(k);i++)
using namespace std;
const int L=1005;
const int N=L*L;
const int dx[8]={-1,-1,-1, 0,0, 1,1,1};
const int dy[8]={-1, 0, 1,-1,1,-1,0,1};
char s[L][L];
vector<int> V[N];
set<int> mp[N];
int id[L][L],fa[N];
int n,m,q,S,T;
int X[N],Y[N];
int top,cnt;
int sta[N*2];
int get(int x){
	return fa[x]==x?x:fa[x]=get(fa[x]);
}
int get2(int x){
	for (;x!=fa[x];x=fa[x]);
	return x;
}
void merge(int x,int y){
	x=get(x); y=get(y);
	if (x!=y) fa[x]=y;
}
void merge2(int x,int y){
	x=get2(x); y=get2(y);
	if (x!=y){
		sta[++top]=x;
		sta[++top]=-y;
		fa[x]=y;
		V[y].push_back(-x);
	}
}
void dfs(int x,vector<int> &v){
	For(i,0,V[x].size()-1){
		int y=V[x][i];
		if (y>0) v.push_back(y);
		else dfs(-y,v);
	}
}
int solve(){
	int p;
	scanf("%d",&p);
	For(i,1,p){
		int x,y;
		scanf("%d%d",&x,&y);
		if (s[x][y]=='#') continue;
		For(k,0,7){
			int X=x+dx[k],Y=y+dy[k];
			if (s[X][Y]!='#') continue;
			merge2(id[x][y],id[X][Y]);
		}
		if (x==n||y==1)
			merge2(S,id[x][y]);
		if (x==1||y==m)
			merge2(T,id[x][y]);
		s[x][y]='#';
		X[++X[0]]=x;
		Y[X[0]]=y;
	}
	if (get2(S)==get2(T))
		return 0;
	vector<int> Vs,Vt;
	dfs(get2(S),Vs);
	dfs(get2(T),Vt);
	For(i,0,Vs.size()-1)
		For(j,0,Vt.size()-1){
			int a=Vs[i],b=Vt[j];
			if (a>b) swap(a,b);
			if (mp[a].find(b)!=mp[a].end())
				return 0;
		}
	For(i,1,X[0]){
		int x=X[i],y=Y[i];
		For(p,x-2,x+2) For(q,y-2,y+2){
			if (p<0||p>n+1||q<0||q>m+1) continue;
			if (get2(id[x][y])==get2(S)&&get2(id[p][q])==get2(T)) return 0;
			if (get2(id[x][y])==get2(T)&&get2(id[p][q])==get2(S)) return 0;
		}
	}
	return 1;
}
int main(){
	scanf("%d%d%d",&n,&m,&q);
	For(i,1,n) scanf("%s",s[i]+1);
	if (s[1][1]=='#'||s[n][m]=='#'){
		For(i,1,q) puts("NO");
		return 0;
	}
	S=++cnt; T=++cnt;
	For(i,2,n) id[i][0]=S,s[i][0]='#';
	For(i,1,m-1) id[n+1][i]=S,s[n+1][i]='#';
	For(i,2,m) id[0][i]=T,s[0][i]='#';
	For(i,1,n-1) id[i][m+1]=T,s[i][m+1]='#';
	For(i,1,n) For(j,1,m) id[i][j]=++cnt;
	For(i,1,cnt) fa[i]=i;
	For(i,1,n) For(j,1,m)
		if (s[i][j]=='#')
			For(k,0,7){
				int x=i+dx[k],y=j+dy[k];
				if (s[x][y]=='#') merge(id[i][j],id[x][y]);
			}
	For(i,1,n) For(j,1,m)
		if (s[i][j]=='.'){
			if (i+j==2) continue;
			if (i+j==n+m) continue;
			For(k,0,7){
				int x=i+dx[k],y=j+dy[k];
				if (s[x][y]!='#') continue;
				For(l,k+1,7){
					int X=i+dx[l],Y=j+dy[l];
					if (s[X][Y]!='#') continue;
					int a=get(id[x][y]),b=get(id[X][Y]);
					if (a==b) continue;
					if (a>b) swap(a,b);
					mp[a].insert(b);
				}
			}
		}
	For(i,1,cnt)
		if (get(i)==i) V[i].push_back(i);
	For(i,1,q){
		puts(solve()?"YES":"NO");
		fflush(stdout);
		For(j,1,X[0])
			s[X[j]][Y[j]]='.';
		X[0]=0;
		for (;top;top--){
			int x=sta[top];
			if (x>0) fa[x]=x;
			else V[-x].pop_back();
		}
	}
}


#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;

typedef long long LL;
typedef pair < int, int > pa;

const int MAXN = 1005;
const int MAXM = 1000005;
const int dx[] = { 1, 1, 1, 0, 0, -1, -1, -1 };
const int dy[] = { 1, 0, -1, 1, -1, 1, 0, -1 };

int fa[MAXM], id_cnt, id[MAXN][MAXN], S, T, n, m, Q, st[MAXN], top, cnt, blkx[MAXN], blky[MAXN];
char ch[MAXN][MAXN];
bool haveans = 1;
set < pa > s;

inline int find(int x) { return fa[ x ] == x ? x : fa[ x ] = find( fa[ x ] ); }
inline int find2(int x) { return fa[ x ] == x ? x : find2( fa[ x ] ); }
inline void merge(int x, int y) { fa[ find2( x ) ] = fa[ find2( y ) ]; }
inline pa make(int x, int y) { return mp( min( x, y ), max( x, y ) ); }

int main()
{
#ifdef wxh010910
freopen( "data.in", "r", stdin );
#endif
scanf( "%d%d%d", &n, &m, &Q );
for( int i = 1 ; i <= n ; i++ ) scanf( "%s", ch[ i ] + 1 );
for( int i = 1 ; i <= n ; i++ ) for( int j = 1 ; j <= m ; j++ ) id[ i ][ j ] = ++id_cnt;
S = ++id_cnt; T = ++id_cnt;
for( int i = 1 ; i <= id_cnt ; i++ ) fa[ i ] = i;
for( int i = 1 ; i <= n ; i++ ) id[ i ][ 0 ] = S, id[ i ][ m + 1 ] = T, ch[ i ][ 0 ] = ch[ i ][ m + 1 ] = '#';
for( int i = 1 ; i <= m ; i++ ) id[ 0 ][ i ] = T, id[ n + 1 ][ i ] = S, ch[ 0 ][ i ] = ch[ n + 1 ][ i ] = '#';
for( int i = 1 ; i <= n ; i++ )
for( int j = 1 ; j <= m ; j++ ) if( ch[ i ][ j ] == '#' )
for( int k = 0 ; k < 8 ; k++ )
{
int x = i + dx[ k ], y = j + dy[ k ];
if( ch[ x ][ y ] == '#' ) fa[ find( id[ i ][ j ] ) ] = find( id[ x ][ y ] );
}
for( int i = 1 ; i <= id_cnt ; i++ ) find( i );
for( int i = 1 ; i <= n ; i++ )
for( int j = 1 ; j <= m ; j++ )
{
if( i == 1 && j == 1 ) continue;
if( i == n && j == m ) continue;
for( int k = 0 ; k < 8 ; k++ )
for( int l = k + 1 ; l < 8 ; l++ )
{
s.insert( make( find( id[ i + dx[ k ] ][ j + dy[ k ] ] ), find( id[ i + dx[ l ] ][ j + dy[ l ] ] ) ) );
if( make( find( id[ i + dx[ k ] ][ j + dy[ k ] ] ), find( id[ i + dx[ l ] ][ j + dy[ l ] ] ) ) == mp( find( S ), find( T ) ) ) haveans = false, i = n + 1, j = m + 1 ;
}
}
if( !haveans ) { while( Q-- ) puts( "NO" ); return 0; }
while( Q-- ){scanf( "%d", &cnt );for( int i = 1 ; i <= cnt ; i++ ){scanf( "%d%d", &blkx[ i ], &blky[ i ] ), ch[ blkx[ i ] ][ blky[ i ] ] = '#'; st[ ++top ] = find( id[ blkx[ i ] ][ blky[ i ] ] );for( int k = 0 ; k < 8 ; k++ )if( ch[ blkx[ i ] + dx[ k ] ][ blky[ i ] + dy[ k ] ] == '#' ) st[ ++top ] = find( id[ blkx[ i ] + dx[ k ] ][ blky[ i ] + dy[ k ] ] );}st[ ++top ] = find( S ), st[ ++top ] = find( T ); sort( st + 1, st + top + 1 ); top = unique( st + 1, st + top + 1 ) - st - 1;for( int i = 1 ; i <= cnt ; i++ )for( int k = 0 ; k < 8 ; k++ )if( ch[ blkx[ i ] + dx[ k ] ][ blky[ i ] + dy[ k ] ] == '#' ) merge( id[ blkx[ i ] + dx[ k ] ][ blky[ i ] + dy[ k ] ], id[ blkx[ i ] ][ blky[ i ] ] );bool ans = true;for( int i = 1 ; i <= top && ans ; i++ ) if( find2( st[ i ] ) == find2( S ) )for( int j = 1 ; j <= top && ans ; j++ ) if( find2( st[ j ] ) == find2( T ) && s.find( make( st[ i ], st[ j ] ) ) != s.end() )ans = false;puts( ans ? "YES" : "NO" ); fflush( stdout );for( int i = 1 ; i <= cnt ; i++ ) ch[ blkx[ i ] ][ blky[ i ] ] = '.';while( top ) fa[ st[ top ] ] = st[ top ], top--;}}


#include<bits/stdc++.h>
#define rep(i,start,lim) for(lld i=start;i<lim;i++)
#define repd(i,start,lim) for(lld i=start;i>=lim;i--)
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define sz(a) lld((a).size())
#define all(c) (c).begin(),(c).end()
#define INF         1011111111
#define LLINF       1000111000111000111LL
#define EPS         (double)1e-10
#define MOD         1000000007
#define PI          3.14159265358979323
using namespace std;
typedef long double ldb;
typedef int lld;
lld powm(lld base,lld exp,lld mod=MOD) {lld ans=1;while(exp){if(exp&1) ans=(ans*base)%mod;exp>>=1,base=(base*base)%mod;}return ans;}
lld ctl(char x,char an='a') {return (lld)(x-an);}
char ltc(lld x,char an='a') {return (char)(x+an);}
typedef vector<lld> vlld;
typedef pair<lld,lld> plld;
typedef map<lld,lld> mlld;
typedef set<lld> slld;
#define sync ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define endl '\n'
#define fre freopen("1.in","r",stdin); freopen("1.out","w",stdout);
#define die(x) return cout<<x,0
#define N 200005
//Segment Tree
struct mat{
    lld val[5][5];
};
mat khali;
string s;
struct segTree{
    lld x,y,val;
    mat tree[4*N];
    mat merge(mat a,mat b) {
        mat ret;
        rep(i,0,5) rep(j,0,5) ret.val[i][j]=INF;
        rep(i,0,5) rep(j,0,5) rep(k,0,5) ret.val[i][j]=min(ret.val[i][j],a.val[i][k]+b.val[k][j]);
        return ret;
    }
    void construct(lld low,lld high,lld pos) {
        if(low==high) {
            tree[pos]=khali;
            if(s[low]=='2') tree[pos].val[0][0] = 1, tree[pos].val[0][1] = 0;
            if(s[low]=='0') tree[pos].val[1][1] = 1, tree[pos].val[1][2] = 0;
            if(s[low]=='1') tree[pos].val[2][2] = 1, tree[pos].val[2][3] = 0;
            if(s[low]=='6') tree[pos].val[3][3] = 1, tree[pos].val[4][4] = 1;
            if(s[low]=='7') tree[pos].val[3][3] = 1, tree[pos].val[3][4] = 0;
            return;
        }
        lld mid=(high+low)/2;
        construct(low,mid,2*pos+1);
        construct(mid+1,high,2*pos+2);
        tree[pos]=merge(tree[2*pos+1],tree[2*pos+2]);
    }
    mat query(lld low,lld high,lld pos) {
        if(x<=low && y>=high) return tree[pos];
        if(x>high||y<low) return khali;
        lld mid=(high+low)/2;
        return merge(query(low,mid,2*pos+1),query(mid+1,high,2*pos+2));
    }
}st;
int main() {
    sync;
    rep(i,0,5) rep(j,0,5) khali.val[i][j]=INF;
    rep(i,0,5) khali.val[i][i]=0;
    lld n,q;
    cin>>n>>q>>s;
    s = " " + s;
    st.construct(1,n,0);
    while(q--) {
        cin>>st.x>>st.y;
        mat ans = st.query(1,n,0);
        cout<<(ans.val[0][4]==INF ? -1 : ans.val[0][4])<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,start,lim) for(lld i=start;i<lim;i++)
#define repd(i,start,lim) for(lld i=start;i>=lim;i--)
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define sz(a) lld((a).size())
#define all(c) (c).begin(),(c).end()
#define INF         1011111111
#define LLINF       1000111000111000111LL
#define EPS         (double)1e-10
#define MOD         1000000007
#define PI          3.14159265358979323
using namespace std;
typedef long double ldb;
typedef int lld;
lld powm(lld base,lld exp,lld mod=MOD) {lld ans=1;while(exp){if(exp&1) ans=(ans*base)%mod;exp>>=1,base=(base*base)%mod;}return ans;}
lld ctl(char x,char an='a') {return (lld)(x-an);}
char ltc(lld x,char an='a') {return (char)(x+an);}
typedef vector<lld> vlld;
typedef pair<lld,lld> plld;
typedef map<lld,lld> mlld;
typedef set<lld> slld;
#define sync ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define endl '\n'
#define fre freopen("1.in","r",stdin); freopen("1.out","w",stdout);
#define die(x) return cout<<x,0
#define N 200005
//Segment Tree
struct mat{
    lld val[5][5];
};
mat khali;
string s;
struct segTree{
    lld x,y,val;
    mat tree[4*N];
    mat merge(mat a,mat b) {
        mat ret;
        rep(i,0,5) rep(j,0,5) ret.val[i][j]=INF;
        rep(i,0,5) rep(j,0,5) rep(k,0,5) ret.val[i][j]=min(ret.val[i][j],a.val[i][k]+b.val[k][j]);
        return ret;
    }
    void construct(lld low,lld high,lld pos) {
        if(low==high) {
            tree[pos]=khali;
            if(s[low]=='2') tree[pos].val[0][0] = 1, tree[pos].val[0][1] = 0;
            if(s[low]=='0') tree[pos].val[1][1] = 1, tree[pos].val[1][2] = 0;
            if(s[low]=='1') tree[pos].val[2][2] = 1, tree[pos].val[2][3] = 0;
            if(s[low]=='6') tree[pos].val[3][3] = 1, tree[pos].val[4][4] = 1;
            if(s[low]=='7') tree[pos].val[3][3] = 1, tree[pos].val[3][4] = 0;
            return;
        }
        lld mid=(high+low)/2;
        construct(low,mid,2*pos+1);
        construct(mid+1,high,2*pos+2);
        tree[pos]=merge(tree[2*pos+1],tree[2*pos+2]);
    }
    mat query(lld low,lld high,lld pos) {
        if(x<=low && y>=high) return tree[pos];
        if(x>high||y<low) return khali;
        lld mid=(high+low)/2;
        return merge(query(low,mid,2*pos+1),query(mid+1,high,2*pos+2));
    }
}st;
int main() {
    //sync;
    rep(i,0,5) rep(j,0,5) khali.val[i][j]=INF;
    rep(i,0,5) khali.val[i][i]=0;
    lld n,q;
    cin>>n>>q>>s;
    s = " " + s;
    st.construct(1,n,0);
    while(q--) {
        cin>>st.x>>st.y;
        mat ans = st.query(1,n,0);
        cout<<(ans.val[0][4]==INF ? -1 : ans.val[0][4])<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,start,lim) for(lld i=start;i<lim;i++)
#define repd(i,start,lim) for(lld i=start;i>=lim;i--)
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define sz(a) lld((a).size())
#define all(c) (c).begin(),(c).end()
#define INF         1011111111
#define LLINF       1000111000111000111LL
#define EPS         (double)1e-10
#define MOD         1000000007
#define PI          3.14159265358979323
using namespace std;
typedef long double ldb;
typedef long long lld;
lld powm(lld base,lld exp,lld mod=MOD) {lld ans=1;while(exp){if(exp&1) ans=(ans*base)%mod;exp>>=1,base=(base*base)%mod;}return ans;}
lld ctl(char x,char an='a') {return (lld)(x-an);}
char ltc(lld x,char an='a') {return (char)(x+an);}
typedef vector<lld> vlld;
typedef pair<lld,lld> plld;
typedef map<lld,lld> mlld;
typedef set<lld> slld;
#define sync ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define endl '\n'
#define fre freopen("1.in","r",stdin); freopen("1.out","w",stdout);
#define die(x) return cout<<x,0
#define N 400005
//Segment Tree
struct mat{
    lld val[5][5];
};
mat khali;
string s;
struct segTree{
    lld x,y,val;
    mat tree[4*N];
    mat merge(mat a,mat b) {
        mat ret;
        rep(i,0,5) rep(j,0,5) ret.val[i][j]=LLINF;
        rep(i,0,5) rep(j,0,5) rep(k,0,5) ret.val[i][j]=min(ret.val[i][j],a.val[i][k]+b.val[k][j]);
        return ret;
    }
    void construct(lld low,lld high,lld pos) {
        if(low==high) {
            tree[pos]=khali;
            if(s[low]=='2') tree[pos].val[0][0] = 1, tree[pos].val[0][1] = 0;
            if(s[low]=='0') tree[pos].val[1][1] = 1, tree[pos].val[1][2] = 0;
            if(s[low]=='1') tree[pos].val[2][2] = 1, tree[pos].val[2][3] = 0;
            if(s[low]=='6') tree[pos].val[3][3] = 1, tree[pos].val[4][4] = 1;
            if(s[low]=='7') tree[pos].val[3][3] = 1, tree[pos].val[3][4] = 0;
            return;
        }
        lld mid=(high+low)/2;
        construct(low,mid,2*pos+1);
        construct(mid+1,high,2*pos+2);
        tree[pos]=merge(tree[2*pos+1],tree[2*pos+2]);
    }
    mat query(lld low,lld high,lld pos) {
        if(x<=low && y>=high) return tree[pos];
        if(x>high||y<low) return khali;
        lld mid=(high+low)/2;
        return merge(query(low,mid,2*pos+1),query(mid+1,high,2*pos+2));
    }
}st;
int main() {
    //sync;
    rep(i,0,5) rep(j,0,5) khali.val[i][j]=LLINF;
    rep(i,0,5) khali.val[i][i]=0;
    lld n,q;
    cin>>n>>q>>s;
    s = " " + s;
    st.construct(1,n,0);
    while(q--) {
        cin>>st.x>>st.y;
        mat ans = st.query(1,n,0);
        cout<<(ans.val[0][4]==LLINF ? -1 : ans.val[0][4])<<endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

template<class T> struct rge { T b, e; };
template<class T> rge<T> range(T i, T j) { return rge<T>{i, j}; }
struct debug {
#ifdef LOCAL
    ~debug(){cerr<<endl;}
    template<class T> debug& operator<<(T x){cerr<<boolalpha<<x; return *this;}
    template<class B, class C> debug& operator<<(pair<B, C> x){return *this<<"("<<x.first<<", "<<x.second<<")";}
    template<class T> debug& operator<<(rge<T> x){*this<<"[";for(auto it=x.b;it!=x.e;it++){*this<<", "+2*(it==x.b)<<*it;}return *this<<"]";}
    template<class T> debug& operator<<(vector<T> x){ return *this<<range(x.begin(),x.end());}
#else
    template<class T> debug& operator <<(const T&){return *this;}
#endif
};
#define nav(...) << "[ " << #__VA_ARGS__ ": " << (__VA_ARGS__) << " ] "
using ll = long long;

#define forn(i, n) for(int i = 0; i < int(n); i++)
#define ford(i, n) for(int i = n-1; i >= 0; i--)

template<typename T>
void min_self(T& a, T b) {
    a = min(a, b);
}
template<typename T>
void max_self(T& a, T b) {
    a = max(a, b);
}

const string year = "2017";
string s;
const int inf = 1e7 + 5;

class SegTree {
public:
    struct Node {

        int dp[5][5];

        Node() {
            forn(i, 5) forn(j, 5) {
                dp[i][j] = inf;
                dp[i][i] = 0;
            }
        }

        void merge(Node a, Node b) {
            forn(i, 5) forn(j, 5) dp[i][j] = inf;
            forn(i, 5) forn(j, 5) if(i <= j) {
                for(int k = i; k <= j; k++) {
                    min_self(dp[i][j], a.dp[i][k] + b.dp[k][j]);
                }
            }
        }
    };

    SegTree(int n_) {
        n = n_;
        tree.resize(4*n);
    }

    void build(int i, int L, int R) {
        if(L == R) {
            char c = s[L-1];
            if(c == '2') {
                tree[i].dp[0][1] = 0, tree[i].dp[0][0] = 1;
            }
            if(c == '0') {
                tree[i].dp[1][2] = 0, tree[i].dp[1][1] = 1;
            }
            if(c == '1') {
                tree[i].dp[2][3] = 0, tree[i].dp[2][2] = 1;
            }
            if(c == '6') {
                tree[i].dp[3][3] = 1, tree[i].dp[4][4] = 1;
            }
            if(c == '7') {
                tree[i].dp[3][4] = 0, tree[i].dp[3][3] = 0;
            }
        } else {
            int mid = L + (R - L)/2;
            build(2*i, L, mid);
            build(2*i+1, mid+1, R);
            tree[i].merge(tree[2*i], tree[2*i+1]);
        }

    }

    Node get(int i, int L, int R, int tl, int tr) {
        if(tl > tr) return Node();
        if(L == tl && tr == R) {
            return tree[i];
        } else {
            int mid = L + (R-L)/2;
            Node ans;
            ans.merge(get(2*i, L, mid, tl, min(tr, mid)), get(2*i+1, mid+1, R, max(tl, mid+1), tr));
            return ans;
        }
    }

    int get(int tl, int tr) {
        Node ans = get(1, 1, n, tl, tr);
        int res = ans.dp[0][4];
        forn(i, 5) {
            debug() << range(ans.dp[i], ans.dp[i]+5);
        }
        return res == inf ? -1 : res;
    }

private:
    int n;
    vector<Node> tree;
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n, q;
    cin >> n >> q >> s;
    debug() nav(s);
    SegTree st(n);
    st.build(1, 1, n);
    forn(zzz, q) {
        int a, b;
        cin >> a >> b;
        cout << st.get(a, b) << '\n';
    }
}

//$ dp[i][j] = min deletions to have no "2016" and currently would have prefix of "2017"
            //$ of length j, assuming we have already built a prefix of length i

//$ dp[i][j] = min(a.dp[i][k] + b.dp[k][j]) over all k in [i, ..., j]

//$ base case: dp[i][j] = inf
            //$ when building, if s[i] in "2017"
            //$ dp[idx][idx+1] = 0;

            //$ if s[i] == '6':
                //$ dp[3][3] = 1

// Those who say they can, and those who say they can't - are both usually right.

// Read statement carefully
// Solve on paper first!
// Overflows (long long)

// Author: blondie


#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 7;
int st[4 * N][5][5];
int n, q;
string str;

void build(int v, int l, int r) {
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 5; ++j) {
      st[v][i][j] = INT_MAX;
    }
  }
  if (r - l == 1) {
    for (int i = 0; i < 5; ++i) {
      st[v][i][i] = 0;
    }
    if (str[l] == '2') {
      st[v][0][0] = 1;
      st[v][0][1] = 0;
    } else if (str[l] == '0') {
      st[v][1][1] = 1;
      st[v][1][2] = 0;
    } else if (str[l] == '1') {
      st[v][2][2] = 1;
      st[v][2][3] = 0;
    } else if (str[l] == '7') {
      st[v][3][3] = 1;
      st[v][3][4] = 0;
    } else if (str[l] == '6') {
      st[v][3][3] = 1;
      st[v][4][4] = 1;
    }
    return;
  }
  int half = (l + r) >> 1;
  build(2 * v, l, half);
  build(2 * v + 1, half, r);
  for (int i = 0; i < 5; ++i) {
    for (int j = i; j < 5; ++j) {
      for (int k = j; k < 5; ++k) {
        if (st[2 * v][i][j] == INT_MAX || st[2 * v + 1][j][k] == INT_MAX) {
          continue;
        }
        st[v][i][k] = min(st[v][i][k], st[2 * v][i][j] + st[2 * v + 1][j][k]);
      }
    }
  }
}

vector<vector<int>> get(int v, int l, int r, int lt, int rt) {
  if (r - l <= 0 || rt - lt <= 0 || lt < l || rt > r) {
    vector<vector<int>> res(5, vector<int>(5, INT_MAX));
    for (int i = 0; i < 5; ++i) {
      res[i][i] = 0;
    }
    return res;
  }
  if (l == lt && r == rt) {
    vector<vector<int>> res(5, vector<int>(5));
    for (int i = 0; i < 5; ++i) {
      for (int j = 0; j < 5; ++j) {
        res[i][j] = st[v][i][j];
      }
    }
    return res;
  }
  int half = (l + r) >> 1;
  auto L = get(2 * v, l, half, lt, min(rt, half));
  auto R = get(2 * v + 1, half, r, max(half, lt), rt);
  vector<vector<int>> res(5, vector<int>(5, INT_MAX));
  for (int i = 0; i < 5; ++i) {
    for (int j = i; j < 5; ++j) {
      for (int k = j; k < 5; ++k) {
        if (L[i][j] == INT_MAX || R[j][k] == INT_MAX) {
          continue;
        }
        res[i][k] = min(res[i][k], L[i][j] + R[j][k]);
      }
    }
  }
  return res;
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0); cout.tie(0);

  cin >> n >> q >> str;
  build(1, 0, n);
  for (int i = 0; i < q; ++i) {
    int l, r;
    cin >> l >> r;
    l--; r--;
    auto res = get(1, 0, n, l, r + 1);
    if (res[0][4] == INT_MAX) {
      cout << -1 << "\n";
    } else {
      cout << res[0][4] << "\n";
    }
  }

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 7;
int st[4 * N][5][5];
int n, q;
string str;

void build(int v, int l, int r) {
  if (r - l <= 0) {
    return;
  }
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 5; ++j) {
      st[v][i][j] = INT_MAX;
    }
  }
  if (r - l == 1) {
    for (int i = 0; i < 5; ++i) {
      st[v][i][i] = 0;
    }
    if (str[l] == '2') {
      st[v][0][0] = 1;
      st[v][0][1] = 0;
    } else if (str[l] == '0') {
      st[v][1][1] = 1;
      st[v][1][2] = 0;
    } else if (str[l] == '1') {
      st[v][2][2] = 1;
      st[v][2][3] = 0;
    } else if (str[l] == '7') {
      st[v][3][3] = 1;
      st[v][3][4] = 0;
    } else if (str[l] == '6') {
      st[v][3][3] = 1;
      st[v][4][4] = 1;
    }
    return;
  }
  int half = (l + r) >> 1;
  build(2 * v, l, half);
  build(2 * v + 1, half, r);
  for (int i = 0; i < 5; ++i) {
    for (int j = i; j < 5; ++j) {
      for (int k = j; k < 5; ++k) {
        if (st[2 * v][i][j] == INT_MAX || st[2 * v + 1][j][k] == INT_MAX) {
          continue;
        }
        st[v][i][k] = min(st[v][i][k], st[2 * v][i][j] + st[2 * v + 1][j][k]);
      }
    }
  }
}

vector<vector<int>> get(int v, int l, int r, int lt, int rt) {
  if (r - l <= 0 || rt - lt <= 0 || lt < l || rt > r) {
    vector<vector<int>> res(5, vector<int>(5, INT_MAX));
    for (int i = 0; i < 5; ++i) {
      res[i][i] = 0;
    }
    return res;
  }
  if (l == lt && r == rt) {
    vector<vector<int>> res(5, vector<int>(5));
    for (int i = 0; i < 5; ++i) {
      for (int j = 0; j < 5; ++j) {
        res[i][j] = st[v][i][j];
      }
    }
    return res;
  }
  int half = (l + r) >> 1;
  auto L = get(2 * v, l, half, lt, min(rt, half));
  auto R = get(2 * v + 1, half, r, max(half, lt), rt);
  vector<vector<int>> res(5, vector<int>(5, INT_MAX));
  for (int i = 0; i < 5; ++i) {
    for (int j = i; j < 5; ++j) {
      for (int k = j; k < 5; ++k) {
        if (L[i][j] == INT_MAX || R[j][k] == INT_MAX) {
          continue;
        }
        res[i][k] = min(res[i][k], L[i][j] + R[j][k]);
      }
    }
  }
  return res;
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0); cout.tie(0);

  cin >> n >> q >> str;
  build(1, 0, n);
  for (int i = 0; i < q; ++i) {
    int l, r;
    cin >> l >> r;
    l--; r--;
    auto res = get(1, 0, n, l, r + 1);
    if (res[0][4] == INT_MAX) {
      cout << -1 << "\n";
    } else {
      cout << res[0][4] << "\n";
    }
  }

  return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <set>
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define sscc ios::sync_with_stdio(false);cin.tie(0);
#define ms(a) memset(a,0,sizeof(a))
#define mss(a) memset(a,-1,sizeof(a))
#define msi(a) memset(a,inf,sizeof(a))
using namespace std;

const int maxn=200005;
const int N=5;
int n,m;
char s[N];

struct node{
	int a[N][N];
	void init(){
		for(int i=0;i<N;i++)
			for(int j=0;j<N;j++)
				a[i][j]=(i==j)?0:maxn;
	}

	node operator + (node B){
		node ans;
		for(int i=0;i<N;i++)
			for(int j=0;j<N;j++){
				ans.a[i][j]=maxn;
				for(int k=0;k<N;k++){
					ans.a[i][j]=min(ans.a[i][j],a[i][k]+B.a[k][j]);
				}
			}
		return ans;
	}
}a[maxn<<2];

void build(int l,int r,int alt)
{
	if(l==r){
		a[alt].init();
		if(s[l]=='2')	a[alt].a[0][0]=1,a[alt].a[0][1]=0;
		if(s[l]=='0')	a[alt].a[1][1]=1,a[alt].a[1][2]=0;
		if(s[l]=='1')	a[alt].a[2][2]=1,a[alt].a[2][3]=0;
		if(s[l]=='7')	a[alt].a[3][3]=1,a[alt].a[3][4]=0;
		if(s[l]=='6')	a[alt].a[3][3]=1,a[alt].a[4][4]=1;
		return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,alt<<1);
	build(mid+1,r,alt<<1|1);
	a[alt]=a[alt<<1]+a[alt<<1|1];
}

node query(int l,int r,int alt,int L,int R)
{
	if(L<=l&&r<=R){
		return a[alt];
	}
	int mid=(l+r)>>1;
	if(R<=mid)	return query(l,mid,alt<<1,L,R);
	if(L>mid) return query(mid+1,r,alt<<1|1,L,R);
	return query(l,mid,alt<<1,L,R)+query(mid+1,r,alt<<1|1,L,R);
}

int main()
{
	scanf("%d%d",&n,&m);
	scanf("%s",s+1);
	build(1,n,1);
	while(m--)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		int ans=query(1,n,1,l,r).a[0][4];
		if(ans==maxn)	ans=-1;
		printf("%d\n",ans);
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <set>
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define sscc ios::sync_with_stdio(false);cin.tie(0);
#define ms(a) memset(a,0,sizeof(a))
#define mss(a) memset(a,-1,sizeof(a))
#define msi(a) memset(a,inf,sizeof(a))
using namespace std;

const int maxn=200005;
const int N=5;
int n,m;
char s[N];

struct node{
	int a[N][N];
	void init(){
		for(int i=0;i<N;i++)
			for(int j=0;j<N;j++)
				a[i][j]=(i==j)?0:maxn;
	}

	node operator + (node B){
		node ans;
		for(int i=0;i<N;i++)
			for(int j=0;j<N;j++){
				ans.a[i][j]=maxn;
				for(int k=0;k<N;k++){
					ans.a[i][j]=min(ans.a[i][j],a[i][k]+B.a[k][j]);
				}
			}
		return ans;
	}
}a[maxn<<2];

void build(int l,int r,int alt)
{
	if(l==r){
		a[alt].init();
		if(s[l]=='2')	a[alt].a[0][0]=1,a[alt].a[0][1]=0;
		if(s[l]=='0')	a[alt].a[1][1]=1,a[alt].a[1][2]=0;
		if(s[l]=='1')	a[alt].a[2][2]=1,a[alt].a[2][3]=0;
		if(s[l]=='7')	a[alt].a[3][3]=1,a[alt].a[3][4]=0;
		if(s[l]=='6')	a[alt].a[3][3]=1,a[alt].a[4][4]=1;
		return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,alt<<1);
	build(mid+1,r,alt<<1|1);
	a[alt]=a[alt<<1]+a[alt<<1|1];
}

node query(int l,int r,int alt,int L,int R)
{
	if(L<=l&&r<=R){
		return a[alt];
	}
	int mid=(l+r)>>1;
	if(R<=mid)	return query(l,mid,alt<<1,L,R);
	if(L>mid) return query(mid+1,r,alt<<1|1,L,R);
	return query(l,mid,alt<<1,L,R)+query(mid+1,r,alt<<1|1,L,R);
}

int main()
{
	scanf("%d%d",&n,&m);
	scanf("%s",s+1);
	build(1,n,1);
	while(m--)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		int ans=query(1,n,1,l,r).a[0][4];
		if(ans==maxn)	ans=-1;
		printf("%d\n",ans);
	}
	return 0;
}

/*
5 4
20176

*/


#include<bits/stdc++.h>

typedef long long   ll;

using namespace std;

#define pb push_back
#define pll pair<ll,ll >
#define sz(x) (x).size()
#define all(x) (x).begin(), (x).end()
#define endln '\n'
#define se second
#define fi first
#define cont continue
#define sqr(x) (x) * (x)
//#define max(a,b) ((a) > (b)? (a) : (b))

const ll MaxN = (2e5) + 10;
const ll LogN = 20;
const ll md = 1e9 + 7;
const ll Inf = 1e9;

struct ed {
	ll v[6][6];
	ed() {
		for (int i = 0; i < 6; i++) {
			for (int j = 0; j < 6; j++) {
				v[i][j] = Inf;
			}
		}
	}
};

ed Tree[MaxN * 4];

ed merge(ed a, ed b) {
	ed z;
	for (int i = 0; i < 6; i++) {
		for (int j = i; j < 6; j++) {
			for (int k = j; k < 6; k++) {
				z.v[i][k] = min(z.v[i][k], a.v[i][j] + b.v[j][k]);
			}
		}
	}
	return z;
}
string s;
ll d[] = { 2,0,1,7,6 };
ed f(ll l) {
	ed a;
	for (int i = 0; i < 6; i++) a.v[i][i] = 1;
	for (int i = 0; i < 5; i++) {
		if (i != 3) {
			if (d[i] == s[l] - '0')a.v[i][i + 1] = 0;
			else a.v[i][i] = 0;
		}
	}
	if (s[l] - '0' == 6) a.v[3][5] = 0;
	else if (s[l] - '0' == 7) a.v[3][4] = 0;
	else a.v[3][3] = 0;

	return a;
}

void Build(ll l, ll r, ll id) {
	if (l == r) {
		Tree[id] = f(l);
	}
	else {
		ll mid = (l + r) / 2;
		Build(l, mid, id * 2 + 1);
		Build(mid + 1, r, id * 2 + 2);
		Tree[id] = merge(Tree[id * 2 + 1], Tree[id * 2 + 2]);
	}
}

ed get(ll l, ll r, ll x, ll y, ll id) {
	if (l == x && y == r) {
		return Tree[id];
	}
	else {
		ll mid = (l + r) / 2;
		if (y <= mid) return get(l, mid, x, y, id * 2 + 1);
		else if (x >= mid + 1) return get(mid + 1, r, x,  y, id * 2 + 2);
		else return merge(get(l, mid, x, mid, id * 2 + 1), get(mid + 1, r, mid + 1, y, id * 2 + 2));
	}
}

int main() {

#ifdef LOCAL
	ifstream cin("input.txt");
	ofstream cout("output.txt");
#else
	//ifstream cin("exercise.in");
	//ofstream cout("exercise.out");

#endif // DEBUG

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cerr.tie(0);

	ll N, Q;
	cin >> N >> Q;
	cin >> s;
	Build(0, N - 1, 0);

	while (Q--) {
		ll l, r;
		cin >> l >> r;
		l--;
		r--;
		ed a = get(0, N - 1, l, r, 0);
		if (a.v[0][4] == Inf) cout << -1 << endln;
		else cout << a.v[0][4] << endln;
	}

	return 0;
}


#include<bits/stdc++.h>

typedef long long   ll;

using namespace std;

#define pb push_back
#define pll pair<ll,ll >
#define sz(x) (x).size()
#define all(x) (x).begin(), (x).end()
#define endln '\n'
#define se second
#define fi first
#define cont continue
#define sqr(x) (x) * (x)
//#define max(a,b) ((a) > (b)? (a) : (b))

const ll MaxN = (5000) + 10;
const ll LogN = 20;
const ll md = 1e9 + 7;
const ll Inf = 1e9;

struct ed {
	ll v[6][6];
	ed() {
		for (int i = 0; i < 6; i++) {
			for (int j = 0; j < 6; j++) {
				v[i][j] = Inf;
			}
		}
	}
};

ed Tree[MaxN * 4];

ed merge(ed a, ed b) {
	ed z;
	for (int i = 0; i < 6; i++) {
		for (int j = i; j < 6; j++) {
			for (int k = j; k < 6; k++) {
				z.v[i][k] = min(z.v[i][k], a.v[i][j] + b.v[j][k]);
			}
		}
	}
	return z;
}
string s;
ll d[] = { 2,0,1,7,6 };
ed f(ll l) {
	ed a;
	for (int i = 0; i < 6; i++) a.v[i][i] = 1;
	for (int i = 0; i < 5; i++) {
		if (i != 3) {
			if (d[i] == s[l] - '0')a.v[i][i + 1] = 0;
			else a.v[i][i] = 0;
		}
	}
	if (s[l] - '0' == 6) a.v[3][5] = 0;
	else if (s[l] - '0' == 7) a.v[3][4] = 0;
	else a.v[3][3] = 0;

	return a;
}

void Build(ll l, ll r, ll id) {
	if (l == r) {
		Tree[id] = f(l);
	}
	else {
		ll mid = (l + r) / 2;
		Build(l, mid, id * 2 + 1);
		Build(mid + 1, r, id * 2 + 2);
		Tree[id] = merge(Tree[id * 2 + 1], Tree[id * 2 + 2]);
	}
}

ed get(ll l, ll r, ll x, ll y, ll id) {
	if (l == x && y == r) {
		return Tree[id];
	}
	else {
		ll mid = (l + r) / 2;
		if (y <= mid) return get(l, mid, x, y, id * 2 + 1);
		else if (x >= mid + 1) return get(mid + 1, r, x,  y, id * 2 + 2);
		else return merge(get(l, mid, x, mid, id * 2 + 1), get(mid + 1, r, mid + 1, y, id * 2 + 2));
	}
}

int main() {

#ifdef LOCAL
	ifstream cin("input.txt");
	ofstream cout("output.txt");
#else
	//ifstream cin("exercise.in");
	//ofstream cout("exercise.out");

#endif // DEBUG

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cerr.tie(0);

	ll N, Q;
	cin >> N >> Q;
	cin >> s;
	Build(0, N - 1, 0);

	while (Q--) {
		ll l, r;
		cin >> l >> r;
		l--;
		r--;
		ed a = get(0, N - 1, l, r, 0);
		if (a.v[0][4] == Inf) cout << -1 << endln;
		else cout << a.v[0][4] << endln;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
int n, q;
const int maxN = 2 * (int)1e5 + 10;
struct node{
    int state[5][5];
    node(){
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                state[i][j] = 0;
            }
        }
    }
};
char s[maxN];
node t[4 * maxN];
string k216 = "2016";
const int INF = (int)1e9;
node merge(const node& a, const node& b) {
    node c;
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            c.state[i][j] = INF;
        }
    }
    for (int st = 0; st < 5; st++) {
        for (int en = st; en < 5; en++) {
            for (int bet = st; bet <= en; bet++) {
                c.state[st][en] = min(c.state[st][en], a.state[st][bet] + b.state[bet][en]);
            }
        }
    }
    return c;
}
void build(int v, int tl, int tr) {
    if (tl == tr) {
        for (int i = 0; i < 5; i++) {
            for (int j = i; j < 5; j++) {
                if (j > i + 1) {
                    t[v].state[i][j] = INF;
                }
                else if (j == i) {
                    t[v].state[i][j] = (k216[i] == s[tl]);
                }
                else {
                    if (k216[i] == s[tl]) t[v].state[i][j] = 0;
                    else t[v].state[i][j] = INF;
                }
            }
        }
        return ;
    }
    int tm = (tl + tr) / 2;
    build(v + v, tl, tm);
    build(v + v + 1, tm + 1, tr);
    t[v] = merge(t[v + v], t[v + v + 1]);
}
int before[maxN];
int pref6[maxN];
node get(int v, int tl, int tr, int l, int r) {
    if (tl == l && tr == r) return t[v];
    int tm = (tl + tr) / 2;
    if (r <= tm) return get(v + v, tl, tm, l, r);
    else if (l > tm) return get(v + v + 1, tm + 1, tr, l, r);
    else return merge(get(v + v, tl, tm, l, tm), get(v + v + 1, tm + 1, tr, tm + 1, r));
}
int main() {
    srand(1488);
    //freopen("input.txt", "r", stdin);
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        cin >> s[i];
        pref6[i] = pref6[i - 1] + (s[i] == '6');
    }
    before[0] = 0;
    for (int i = 1; i <= n; i++) {
        before[i] = before[i - 1];
        if (s[i] == '7') before[i] = i;
    }
    build(1, 1, n);
    for (int i = 1; i <= q; i++) {
        int a, b;
        cin >> a >> b;
        int x = before[b];
        if (x < a) {
            cout << -1 << '\n';
            continue;
        }
        int ans = pref6[b] - pref6[x - 1];
        node c = get(1, 1, n, a, x - 1);
        ans += c.state[0][3];
        /*for (int ii = 0; ii < 5; ii++) {
            for (int jj = 0; jj < 5; jj++) {
                cout << c.state[ii][jj  ] << " ";
            }
            cout << '\n';
        }*/
        if (ans > n) {
            cout << -1 << '\n';
        }
        else {
            cout << ans << '\n';
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
int n, q;
const int maxN = 2 * (int)1e5 + 10;
struct node{
    int state[4][4];
    node(){
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                state[i][j] = 0;
            }
        }
    }
};
char s[maxN];
node t[4 * maxN];
string k216 = "2016";
const int INF = (int)1e9;
node merge(const node& a, const node& b) {
    node c;
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            c.state[i][j] = INF;
        }
    }
    for (int st = 0; st < 4; st++) {
        for (int en = st; en < 4; en++) {
            for (int bet = st; bet <= en; bet++) {
                c.state[st][en] = min(c.state[st][en], a.state[st][bet] + b.state[bet][en]);
            }
        }
    }
    return c;
}
void build(int v, int tl, int tr) {
    if (tl == tr) {
        for (int i = 0; i < 4; i++) {
            for (int j = i; j < 4; j++) {
                if (j > i + 1) {
                    t[v].state[i][j] = INF;
                }
                else if (j == i) {
                    t[v].state[i][j] = (k216[i] == s[tl]);
                }
                else {
                    if (k216[i] == s[tl]) t[v].state[i][j] = 0;
                    else t[v].state[i][j] = INF;
                }
            }
        }
        return ;
    }
    int tm = (tl + tr) / 2;
    build(v + v, tl, tm);
    build(v + v + 1, tm + 1, tr);
    t[v] = merge(t[v + v], t[v + v + 1]);
}
int before[maxN];
int pref6[maxN];
node get(int v, int tl, int tr, int l, int r) {
    if (tl == l && tr == r) return t[v];
    int tm = (tl + tr) / 2;
    if (r <= tm) return get(v + v, tl, tm, l, r);
    else if (l > tm) return get(v + v + 1, tm + 1, tr, l, r);
    else return merge(get(v + v, tl, tm, l, tm), get(v + v + 1, tm + 1, tr, tm + 1, r));
}
int main() {
    srand(1488);
    //freopen("input.txt", "r", stdin);
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        cin >> s[i];
        pref6[i] = pref6[i - 1] + (s[i] == '6');
    }
    before[0] = 0;
    for (int i = 1; i <= n; i++) {
        before[i] = before[i - 1];
        if (s[i] == '7') before[i] = i;
    }
    build(1, 1, n);
    for (int i = 1; i <= q; i++) {
        int a, b;
        cin >> a >> b;
        int x = before[b];
        if (x < a) {
            cout << -1 << '\n';
            continue;
        }
        int ans = pref6[b] - pref6[x - 1];
        node c = get(1, 1, n, a, x);
        ans += c.state[0][3];
        /*for (int ii = 0; ii < 5; ii++) {
            for (int jj = 0; jj < 5; jj++) {
                cout << c.state[ii][jj  ] << " ";
            }
            cout << '\n';
        }*/
        if (ans > n) {
            cout << -1 << '\n';
        }
        else {
            cout << ans << '\n';
        }
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
int n, q;
const int maxN = 2 * (int)1e5 + 10;
struct node{
    int state[4][4];
    node(){
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                state[i][j] = 0;
            }
        }
    }
};
char s[maxN];
node t[4 * maxN];
string k216 = "2016";
const int INF = (int)1e9;
node merge(const node& a, const node& b) {
    node c;
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            c.state[i][j] = INF;
        }
    }
    for (int st = 0; st < 4; st++) {
        for (int en = st; en < 4; en++) {
            for (int bet = st; bet <= en; bet++) {
                c.state[st][en] = min(c.state[st][en], a.state[st][bet] + b.state[bet][en]);
            }
        }
    }
    return c;
}
void build(int v, int tl, int tr) {
    if (tl == tr) {
        for (int i = 0; i < 4; i++) {
            for (int j = i; j < 4; j++) {
                if (j > i + 1) {
                    t[v].state[i][j] = INF;
                }
                else if (j == i) {
                    t[v].state[i][j] = (k216[i] == s[tl]);
                }
                else {
                    if (k216[i] == s[tl]) t[v].state[i][j] = 0;
                    else t[v].state[i][j] = INF;
                }
            }
        }
        return ;
    }
    int tm = (tl + tr) / 2;
    build(v + v, tl, tm);
    build(v + v + 1, tm + 1, tr);
    t[v] = merge(t[v + v], t[v + v + 1]);
}
int before[maxN];
int pref6[maxN];
node get(int v, int tl, int tr, int l, int r) {
    if (tl == l && tr == r) return t[v];
    int tm = (tl + tr) / 2;
    if (r <= tm) return get(v + v, tl, tm, l, r);
    else if (l > tm) return get(v + v + 1, tm + 1, tr, l, r);
    else return merge(get(v + v, tl, tm, l, tm), get(v + v + 1, tm + 1, tr, tm + 1, r));
}
int main() {
    srand(1488);
    //freopen("input.txt", "r", stdin);
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        cin >> s[i];
        pref6[i] = pref6[i - 1] + (s[i] == '6');
    }
    before[0] = 0;
    for (int i = 1; i <= n; i++) {
        before[i] = before[i - 1];
        if (s[i] == '7') before[i] = i;
    }
    build(1, 1, n);
    for (int i = 1; i <= q; i++) {
        int a, b;
        cin >> a >> b;
        int x = before[b];
        if (x < a) {
            cout << -1 << '\n';
            continue;
        }
        int ans = pref6[b] - pref6[x - 1];
        node c = get(1, 1, n, a, x - 1);
        ans += c.state[0][3];
        /*for (int ii = 0; ii < 5; ii++) {
            for (int jj = 0; jj < 5; jj++) {
                cout << c.state[ii][jj  ] << " ";
            }
            cout << '\n';
        }*/
        if (ans > n) {
            cout << -1 << '\n';
        }
        else {
            cout << ans << '\n';
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int dir[8][2]={{1,0},{0,1},{1,1},{1,-1},{-1,1},{-1,-1},{0,-1},{-1,0}};
#define pi acos(-1)
#define ls rt<<1
#define rs rt<<1|1
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
#define llinf 1e18
#define inf 1e9
const int N=2e5+6;
inline int read() {
    char c=getchar(); int x=0, f=1;
    while(c<'0'|c>'9') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
ll exgcd(ll a,ll b){
	if(b==0) return a;
	exgcd(b,a%b);
}
ll q_pow(ll a,ll b,ll mod){
	ll anss=1;
	while(b){
		if(b&1) anss=anss*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return anss;
}
ll q_mul(ll a,ll b,ll mod){
	ll anss=0;
	while(b){
		if(b&1) anss=(anss+a)%mod;
		a=(a+a)%mod;
		b>>=1;
	}
	return anss;
}
char s[N];
struct node{
	int mat[5][5];  //表示状态i转移到j的最小代价
	node operator + (node x){
		node ans;
		for(int i=0;i<5;i++){
			for(int j=0;j<5;j++){
				ans.mat[i][j]=N;
				for(int k=0;k<5;k++){
					ans.mat[i][j]=min(ans.mat[i][j],mat[i][k]+x.mat[k][j]);
				}
			}
		}
		return ans;
	}
}a[N<<2];
void pushup(int rt){
	a[rt]=a[ls]+a[rs];
}
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++){
				a[rt].mat[i][j]=(i==j)?0:N;
			}
		}
		if(s[l]=='2') a[rt].mat[0][1]=0,a[rt].mat[0][0]=1;
		if(s[l]=='0') a[rt].mat[1][2]=0,a[rt].mat[1][1]=1;
		if(s[l]=='1') a[rt].mat[2][3]=0,a[rt].mat[2][2]=1;
		if(s[l]=='7') a[rt].mat[3][4]=0,a[rt].mat[3][3]=1;
		if(s[l]=='6') a[rt].mat[3][3]=1,a[rt].mat[4][4]=1;
		return ;
	}
	int m=(l+r)>>1;
	build(l,m,ls);
	build(m+1,r,rs);
	pushup(rt);
}
node query(int l,int r,int L,int R,int rt){
	if(L<=l&&r<=R) return a[rt];
	int m=(l+r)>>1;
	if(l<=m) return query(l,m,L,R,ls);
	if(r>m) return query(m+1,r,L,R,rs);
	return query(l,m,L,R,ls)+query(m+1,r,L,R,rs);
}
int main(int argc, char * argv[]) {
    ios::sync_with_stdio(false);
	int n,q;
	while(~scanf("%d%d%s",&n,&q,s+1)) {
		build(1,n,1);
		while(q--) {
			int l,r;
			scanf("%d%d",&l,&r);
			int ans=query(1,n,l,r,1).mat[0][4];
			if(ans==N) ans=-1;
			printf("%d\n",ans);
		}
	}
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int dir[8][2]={{1,0},{0,1},{1,1},{1,-1},{-1,1},{-1,-1},{0,-1},{-1,0}};
#define pi acos(-1)
#define ls rt<<1
#define rs rt<<1|1
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
#define llinf 1e18
#define inf 1e9
const int N=2e5+6;
inline int read() {
    char c=getchar(); int x=0, f=1;
    while(c<'0'|c>'9') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
ll exgcd(ll a,ll b){
	if(b==0) return a;
	exgcd(b,a%b);
}
ll q_pow(ll a,ll b,ll mod){
	ll anss=1;
	while(b){
		if(b&1) anss=anss*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return anss;
}
ll q_mul(ll a,ll b,ll mod){
	ll anss=0;
	while(b){
		if(b&1) anss=(anss+a)%mod;
		a=(a+a)%mod;
		b>>=1;
	}
	return anss;
}
char s[N];
struct node{
	int mat[5][5];  //表示状态i转移到j的最小代价
	node operator + (node x){
		node ans;
		for(int i=0;i<5;i++){
			for(int j=0;j<5;j++){
				ans.mat[i][j]=N;
				for(int k=0;k<5;k++){
					ans.mat[i][j]=min(ans.mat[i][j],mat[i][k]+x.mat[k][j]);
				}
			}
		}
		return ans;
	}
}a[N<<2];
void pushup(int rt){
	a[rt]=a[ls]+a[rs];
}
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++){
				a[rt].mat[i][j]=(i==j)?0:N;
			}
		}
		if(s[l]=='2') a[rt].mat[0][1]=0,a[rt].mat[0][0]=1;
		if(s[l]=='0') a[rt].mat[1][2]=0,a[rt].mat[1][1]=1;
		if(s[l]=='1') a[rt].mat[2][3]=0,a[rt].mat[2][2]=1;
		if(s[l]=='7') a[rt].mat[3][4]=0,a[rt].mat[3][3]=1;
		if(s[l]=='6') a[rt].mat[3][3]=1,a[rt].mat[4][4]=1;
		return ;
	}
	int m=(l+r)>>1;
	build(l,m,ls);
	build(m+1,r,rs);
	pushup(rt);
}
node query(int l,int r,int L,int R,int rt){
	if(L<=l&&r<=R) return a[rt];
	int m=(l+r)>>1;
	if(m<L) return query(m+1,r,L,R,rs);
	if(m>=R) return query(l,m,L,R,ls);
	return query(l,m,L,R,ls)+query(m+1,r,L,R,rs);
}
int main(int argc, char * argv[]) {
    ios::sync_with_stdio(false);
	int n,q;
	while(~scanf("%d%d%s",&n,&q,s+1)) {
		build(1,n,1);
		while(q--) {
			int l,r;
			scanf("%d%d",&l,&r);
			int ans=query(1,n,l,r,1).mat[0][4];
			if(ans==N) ans=-1;
			printf("%d\n",ans);
		}
	}
    return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
const int N=200005;
char s[N];
struct Node {
	int mat[5][5];
	Node operator + (Node x) {
		Node ans;
		for(int i=0;i<5;++i) {
			for(int j=0;j<5;++j) {
				ans.mat[i][j]=N;
				for(int k=0;k<5;++k) {
					ans.mat[i][j]=min(ans.mat[i][j],mat[i][k]+x.mat[k][j]);
				}
			}
		}
		return ans;
	}
}a[N<<2];
void build(int l,int r,int x) {
	if(l==r) {
		for(int i=0;i<5;++i) {
			for(int j=0;j<5;++j) {
				a[x].mat[i][j]=(i==j)?0:N;
			}
		}
		if(s[l]=='2') a[x].mat[0][1]=0,a[x].mat[0][0]=1;
		if(s[l]=='0') a[x].mat[1][2]=0,a[x].mat[1][1]=1;
		if(s[l]=='1') a[x].mat[2][3]=0,a[x].mat[2][2]=1;
		if(s[l]=='7') a[x].mat[3][4]=0,a[x].mat[3][3]=1;
		if(s[l]=='6') a[x].mat[3][3]=1,a[x].mat[4][4]=1;
		return ;
	}
	int m=l+r>>1;
	build(l,m,x<<1);build(m+1,r,x<<1|1);
	a[x]=a[x<<1]+a[x<<1|1];
}
Node query(int l,int r,int L,int R,int x) {
	if(L<=l&&r<=R) return a[x];
	int m=l+r>>1;
	if(m<L) return query(m+1,r,L,R,x<<1|1);
	if(m>=R) return query(l,m,L,R,x<<1);
	return query(l,m,L,R,x<<1)+query(m+1,r,L,R,x<<1|1);
}
int main() {
	int n,q;
	while(~scanf("%d%d%s",&n,&q,s+1)) {
		build(1,n,1);
		while(q--) {
			int l,r;
			scanf("%d%d",&l,&r);
			int ans=query(1,n,l,r,1).mat[0][4];
			if(ans==N) ans=-1;
			printf("%d\n",ans);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int dir[8][2]={{1,0},{0,1},{1,1},{1,-1},{-1,1},{-1,-1},{0,-1},{-1,0}};
#define pi acos(-1)
#define ls rt<<1
#define rs rt<<1|1
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
#define llinf 1e18
#define inf 1e9
const int N=2e5+6;
inline int read() {
    char c=getchar(); int x=0, f=1;
    while(c<'0'|c>'9') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
ll exgcd(ll a,ll b){
	if(b==0) return a;
	exgcd(b,a%b);
}
ll q_pow(ll a,ll b,ll mod){
	ll anss=1;
	while(b){
		if(b&1) anss=anss*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return anss;
}
ll q_mul(ll a,ll b,ll mod){
	ll anss=0;
	while(b){
		if(b&1) anss=(anss+a)%mod;
		a=(a+a)%mod;
		b>>=1;
	}
	return anss;
}
char s[N];
struct node{
	int mat[5][5];  //表示状态i转移到j的最小代价
	node operator + (node x){
		node ans;
		for(int i=0;i<5;i++){
			for(int j=0;j<5;j++){
				ans.mat[i][j]=N;
				for(int k=0;k<5;k++){
					ans.mat[i][j]=min(ans.mat[i][j],mat[i][k]+x.mat[k][j]);
				}
			}
		}
		return ans;
	}
}a[N<<2];
void pushup(int rt){
	a[rt]=a[ls]+a[rs];
}
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++){
				a[rt].mat[i][j]=(i==j)?0:N;
			}
		}
		if(s[l]=='2') a[rt].mat[0][1]=0,a[rt].mat[0][0]=1;
		if(s[l]=='0') a[rt].mat[1][2]=0,a[rt].mat[1][1]=1;
		if(s[l]=='1') a[rt].mat[2][3]=0,a[rt].mat[2][2]=1;
		if(s[l]=='7') a[rt].mat[3][4]=0,a[rt].mat[3][3]=1;
		if(s[l]=='6') a[rt].mat[3][3]=1,a[rt].mat[4][4]=1;
		return ;
	}
	int m=(l+r)>>1;
	build(l,m,ls);
	build(m+1,r,rs);
	pushup(rt);
}
node query(int l,int r,int L,int R,int rt){
	if(L<=l&&r<=R) return a[rt];
	int m=(l+r)>>1;
	if(L>=m) return query(l,m,L,R,ls);
	if(R<m) return query(m+1,r,L,R,rs);
	return query(l,m,L,R,ls)+query(m+1,r,L,R,rs);
}
int main(int argc, char * argv[]) {
    ios::sync_with_stdio(false);
	int n,q;
	while(~scanf("%d%d%s",&n,&q,s+1)) {
		build(1,n,1);
		while(q--) {
			int l,r;
			scanf("%d%d",&l,&r);
			int ans=query(1,n,l,r,1).mat[0][4];
			if(ans==N) ans=-1;
			printf("%d\n",ans);
		}
	}
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int dir[8][2]={{1,0},{0,1},{1,1},{1,-1},{-1,1},{-1,-1},{0,-1},{-1,0}};
#define pi acos(-1)
#define ls rt<<1
#define rs rt<<1|1
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
#define llinf 1e18
#define inf 1e9
const int N=2e5+6;
inline int read() {
    char c=getchar(); int x=0, f=1;
    while(c<'0'|c>'9') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
ll exgcd(ll a,ll b){
	if(b==0) return a;
	exgcd(b,a%b);
}
ll q_pow(ll a,ll b,ll mod){
	ll anss=1;
	while(b){
		if(b&1) anss=anss*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return anss;
}
ll q_mul(ll a,ll b,ll mod){
	ll anss=0;
	while(b){
		if(b&1) anss=(anss+a)%mod;
		a=(a+a)%mod;
		b>>=1;
	}
	return anss;
}
char s[N];
struct node{
	int mat[5][5];  //表示状态i转移到j的最小代价
	node operator + (node x){
		node ans;
		for(int i=0;i<5;i++){
			for(int j=0;j<5;j++){
				ans.mat[i][j]=N;
				for(int k=0;k<5;k++){
					ans.mat[i][j]=min(ans.mat[i][j],mat[i][k]+x.mat[k][j]);
				}
			}
		}
		return ans;
	}
}a[N<<2];
void pushup(int rt){
	a[rt]=a[ls]+a[rs];
}
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++){
				a[rt].mat[i][j]=(i==j)?0:N;
			}
		}
		if(s[l]=='2') a[rt].mat[0][1]=0,a[rt].mat[0][0]=1;
		if(s[l]=='0') a[rt].mat[1][2]=0,a[rt].mat[1][1]=1;
		if(s[l]=='1') a[rt].mat[2][3]=0,a[rt].mat[2][2]=1;
		if(s[l]=='7') a[rt].mat[3][4]=0,a[rt].mat[3][3]=1;
		if(s[l]=='6') a[rt].mat[3][3]=1,a[rt].mat[4][4]=1;
		return ;
	}
	int m=(l+r)>>1;
	build(l,m,ls);
	build(m+1,r,rs);
	pushup(rt);
}
node query(int l,int r,int L,int R,int rt){
	if(L<=l&&r<=R) return a[rt];
	int m=(l+r)>>1;
	if(m<L) return query(m+1,r,L,R,ls);
	if(m>=R) return query(l,m,L,R,rs);
	return query(l,m,L,R,ls)+query(m+1,r,L,R,rs);
}
int main(int argc, char * argv[]) {
    ios::sync_with_stdio(false);
	int n,q;
	while(~scanf("%d%d%s",&n,&q,s+1)) {
		build(1,n,1);
		while(q--) {
			int l,r;
			scanf("%d%d",&l,&r);
			int ans=query(1,n,l,r,1).mat[0][4];
			if(ans==N) ans=-1;
			printf("%d\n",ans);
		}
	}
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
struct Mat
{
	int t[5][5];
	Mat() { memset(t, 0, sizeof t); }
}tr[N << 2];
char a[N];
Mat operator + (Mat a, Mat b)
{
	Mat c;
	for (int i = 0; i < 5; i++)
		for (int j = 0; j < 5; j++) {
			c.t[i][j] = N;
			for (int k = 0; k < 5; k++)
				c.t[i][j] = min(c.t[i][j], a.t[i][k] + b.t[k][j]);
		}
	return c;
}
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) {
				tr[rt].t[i][j] = (i == j) ? 0 : N;
			}
		}
		if (a[l] == '2') tr[rt].t[0][1] = 0, tr[rt].t[0][0] = 1;
		if (a[l] == '0') tr[rt].t[1][2] = 0, tr[rt].t[1][1] = 1;
		if (a[l] == '1') tr[rt].t[2][3] = 0, tr[rt].t[2][2] = 1;
		if (a[l] == '7') tr[rt].t[3][4] = 0, tr[rt].t[3][3] = 1;
		if (a[l] == '6') tr[rt].t[3][3] = 1, tr[rt].t[4][4] = 1;
		return;
	}
	int mid = l + r >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	tr[rt] = tr[rt << 1] + tr[rt << 1 | 1];
}
Mat query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tr[rt];
	}
	int mid = l + r >> 1;
	Mat x;
	for (int i = 0; i < 5; ++i) {
		for (int j = 0; j < 5; ++j) {
			x.t[i][j] = (i == j) ? 0 : N;
		}
	}
	if (L <= mid)x = x + query(l, mid, rt << 1, L, R);
	if (R > mid)x = x + query(mid + 1, r, rt << 1 | 1, L, R);
	return x;
}
int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	scanf("%s", a + 1);
	build(1, n, 1);
	while (m--) {
		int l, r;
		scanf("%d%d", &l, &r);
		int ans = query(1, n, 1, l, r).t[0][4];
		printf("%d\n", ans == N ? -1 : ans);
	}
}


/* In the name of Allah */
#include<bits/stdc++.h>
using namespace std;

const int N = 2e5 + 5;
string s, t = "2017";
struct node {
	int dp[5][5];
	node(bool base = true) {
		memset(dp, 63, sizeof dp);
		if (base)
			for (int i = 0; i < 5; i++)
				dp[i][i] = 0;
	}
} seg[N << 1];
int n, q;

node merge(node L, node R) {
	node ans(false);
	for (int i = 0; i < 5; i++)
		for (int j = i; j < 5; j++)
			for (int k = j; k < 5; k++)
				ans.dp[i][k] = min(ans.dp[i][k], L.dp[i][j] + R.dp[j][k]);
	return ans;
}

void build() {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < 4; j++)
			if (s[i] == t[j]) {
				seg[n + i].dp[j][j] = 1;
				seg[n + i].dp[j][j + 1] = 0;
			}
		if (s[i] == '6')
			seg[n + i].dp[3][3] = seg[n + i].dp[4][4] = 1;
	}
	for (int i = n - 1; i; i--)
		seg[i] = merge(seg[i << 1], seg[i << 1 | 1]);
}

node get(int l, int r) {
	node L, R;
	for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
		if (l & 1)
			L = merge(L, seg[l++]);
		if (r & 1)
			R = merge(seg[--r], R);
	}
	return merge(L, R);
}

void read_input() {
	cin >> n >> q >> s;
}

void write_output() {
	for (build(); q--; ) {
		int l, r;
		cin >> l >> r;
		int ans = get(--l, r).dp[0][4];
		cout << (ans < r - l? ans: -1) << endl;
	}
}

int main() {
	ios:: sync_with_stdio(0), cin.tie(0), cout.tie(0);
	read_input(), write_output();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=2e5+7;
const int inf=1e8;
const ll inff=1e18;
const ll mod=1e9+7;
#define pii pair<int,int>
#define mkp make_pair
#define F first
#define S second
#define pb push_back
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(),(v).end()
//#define int ll

#ifdef HNO2
#define IOS
#else
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#endif // HNO2

string s;

struct Matrix
{
    int A[5][5];
    Matrix operator+(const Matrix &rhs)const{
        Matrix ret;
        for (int i=0;i<5;i++)
            for (int j=0;j<5;j++)
                ret.A[i][j]=inf;
        for (int k=0;k<5;k++)
            for (int i=0;i<5;i++)
                for (int j=0;j<5;j++) ret.A[i][j]=min(ret.A[i][j],A[i][k]+rhs.A[k][j]);
        return ret;
    }
}seg[maxn*4];

void Build(int now,int l,int r)
{
    if (l==r)
    {
        for (int i=0;i<5;i++)
            for (int j=0;j<5;j++)
                if (i!=j) seg[now].A[i][j]=inf;
                else seg[now].A[i][j]=0;
        if (s[l]=='2') seg[now].A[0][0]=1,seg[now].A[0][1]=0;
        if (s[l]=='0') seg[now].A[1][1]=1,seg[now].A[1][2]=0;
        if (s[l]=='1') seg[now].A[2][2]=1,seg[now].A[2][3]=0;
        if (s[l]=='7') seg[now].A[3][3]=1,seg[now].A[3][4]=0;
        if (s[l]=='6') seg[now].A[3][3]=1,seg[now].A[4][4]=1;
        return;
    }
    int m=(l+r)>>1;
    Build(now*2,l,m);
    Build(now*2+1,m+1,r);
    seg[now]=seg[now*2]+seg[now*2+1];
}

Matrix query(int now,int l,int r,int ql,int qr)
{
    if (l>=ql&&r<=qr) return seg[now];
    int m=(l+r)>>1;
    if (qr<=m) return query(now*2,l,m,ql,qr);
    if (ql>m) return query(now*2+1,m+1,r,ql,qr);
    return query(now*2,l,m,ql,qr)+query(now*2+1,m+1,r,ql,qr);
}

int32_t main()
{
    IOS
    int n,q;
    cin>>n>>q;
    cin>>s;
    s="#"+s;
    Build(1,1,n);
    while (q--)
    {
        int l,r;
        cin>>l>>r;
        Matrix ret=query(1,1,n,l,r);
        if (ret.A[0][4]==inf) cout<<-1<<endl;
        else cout<<ret.A[0][4]<<endl;
    }
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5;
const int inf = 1e9;
char s[maxn+11];
struct node
{
	int dp[5][5];
}ST[4*maxn+11],ex[5];
node merge(node a,node b)
{
	node ans;
	int i,j,k;
	for(i=0;i<5;i++)
	{
		for(j=0;j<5;j++)
		{
	 		ans.dp[i][j] = inf;
			for(k=0;k<5;k++)
	 	 	{
				ans.dp[i][j]=min(ans.dp[i][j],a.dp[i][k]+b.dp[k][j]);
			}
	 	}
	}
	return ans;
}
void build(int pos,int l,int r)
{
	int i,j;
	if(l==r)
	{
		for(i=0;i<5;i++)
		{
			for(j=0;j<5;j++)
			{
				if(i==j)			ST[pos].dp[i][j] = 0;
				else				ST[pos].dp[i][j] = inf;
			}
		}
		if(s[l]=='2') 		{ ST[pos].dp[0][1] = 0; ST[pos].dp[0][0] = 1; }
		else if(s[l]=='0') 	{ ST[pos].dp[1][2] = 0; ST[pos].dp[1][1] = 1; }
		else if(s[l]=='1') 	{ ST[pos].dp[2][3] = 0; ST[pos].dp[2][2] = 1; }
		else if(s[l]=='7') 	{ ST[pos].dp[3][4] = 0; ST[pos].dp[3][3] = 1; }
		else if(s[l]=='6') 	{ ST[pos].dp[3][3] = 1; ST[pos].dp[4][4] = 1; }
		return;
	}
	int mid = (l+r)/2;
	build(pos*2,l,mid);
	build(pos*2+1,mid+1,r);
	ST[pos] = merge(ST[pos*2],ST[pos*2+1]);
}
node query(int pos,int begin,int end,int l,int r)
{
	int i,j;
	node ans;
	for(i=0;i<5;i++)
	{
		for(j=0;j<5;j++)
		{
			if(i==j)			ans.dp[i][j] = 0;
			else				ans.dp[i][j] = inf;
		}
	}
	if(begin>r||end<l) 			return ans;
	if(begin>=l&&end<=r) 		return ST[pos];
	int mid=(begin+end)/2;
	return merge(query(pos*2,begin,mid,l,r),query(pos*2+1,mid+1,end,l,r));
}
int main()
{
	int n,q;
	scanf("%d %d %s",&n,&q,s+1);
	build(1,1,n);
	node ans;
	while(q--)
	{
		int l,r;
		scanf("%d %d",&l,&r);
		ans = query(1,1,n,l,r);
		if(ans.dp[0][4]==inf)				printf("-1\n");
		else								printf("%d\n",ans.dp[0][4]);
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>pii;
typedef long long ll;
const int mn=2e5+10;
const ll mod=998244353;
struct vesh{
    int dp[5][5];
};
inline vesh add(vesh a,vesh b){
    vesh c=vesh();
    memset(c.dp,0x3f,sizeof(c.dp));
    for(int i=0;i<=4;i++){
        for(int j=i;j<=4;j++){
            for(int k=i;k<=j;k++){
                c.dp[i][j]=min(c.dp[i][j],a.dp[i][k]+b.dp[k][j]);
            }
        }
    }
    return c;
}
string s;
vesh seg[mn*4];
#define mid ((l+r)>>1)
void init(int x,int l,int r){
    if(l==r){
        for(int i=0;i<=4;i++)seg[x].dp[i][i]=0;
        if(s[l]=='2')seg[x].dp[0][0]=1,seg[x].dp[0][1]=0;
        else if(s[l]=='0')seg[x].dp[1][1]=1,seg[x].dp[1][2]=0;
        else if(s[l]=='1')seg[x].dp[2][2]=1,seg[x].dp[2][3]=0;
        else if(s[l]=='7')seg[x].dp[3][3]=1,seg[x].dp[3][4]=0;
        else if(s[l]=='6')seg[x].dp[3][3]=seg[x].dp[4][4]=1;
    }
    else{
        init(x*2,l,mid);
        init(x*2+1,mid+1,r);
        seg[x]=add(seg[x*2],seg[x*2+1]);
    }
}
vesh query(int x,int l,int r,int a,int b){
    if(l==a&&r==b)return seg[x];
    else{
        if(b<=mid)return query(x*2,l,mid,a,b);
        else if(a>mid)return query(x*2+1,mid+1,r,a,b);
        else return add(query(x*2,l,mid,a,mid),query(x*2+1,mid+1,r,mid+1,b));
    }
}
int main(){
    int n,q;
    scanf("%d%d",&n,&q);
    cin>>s;
    memset(seg,0x3f,sizeof(seg));
    init(1,0,n-1);
    while(q--){
        int a,b;
        scanf("%d%d",&a,&b);
        a--,b--;
        int ans=query(1,0,n-1,a,b).dp[0][4];
        if(ans==0x3f3f3f3f)printf("-1\n");
        else printf("%d\n",ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pi;
typedef long long lint;
const int MAXN = 200005;

struct query{
	int s, e, idx;
};

int n, q, ret[MAXN];
char str[MAXN];
int dl[MAXN][6], dr[MAXN][6];

int code(char c){
	if(c == '2') return 0;
	if(c == '0') return 1;
	if(c == '1') return 2;
	if(c == '6') return 3;
	if(c == '7') return 4;
	return -1;
}

void solve(int s, int e, vector<query> v){
	if(s == e){
		return;
	}
	int m = (s+e)/2;
	vector<query> l, r, x;
	for(auto &i : v){
		if(i.e <= m) l.push_back(i);
		else if(i.s > m) r.push_back(i);
		else x.push_back(i);
	}
	solve(s, m, l);
	solve(m+1, e, r);
	for(int i=0; i<6; i++){
		for(int j=0; j<6; j++){
			dl[m+1][j] = dr[m][j] = 1e9;
		}
		dl[m+1][i] = dr[m][i] = 0;
		for(int j=m; j>=s; j--){
			int val = code(str[j]);
			for(int k=0; k<6; k++){
				if(val == -1){
					dl[j][k] = dl[j+1][k];
				}
				else if(val <= 2){
					if(k == val) dl[j][k] = min(dl[j+1][k] + 1, dl[j+1][k+1]);
					else dl[j][k] = dl[j+1][k];
				}
				else if(val == 3){
					if(k == 3 || k == 4) dl[j][k] = min(dl[j+1][k] + 1, dl[j+1][5]);
					else dl[j][k] = dl[j+1][k];
				}
				else{
					if(k == 3) dl[j][k] = min(dl[j+1][k] + 1, dl[j+1][k+1]);
					else dl[j][k] = dl[j+1][k];
				}
			}
		}
		for(int j=m+1; j<=e; j++){
			int val = code(str[j]);
			for(int k=0; k<6; k++){
				if(val == -1){
					dr[j][k] = dr[j-1][k];
				}
				else if(val <= 2){
					if(k == val+1) dr[j][k] = min(dr[j-1][k] + 1, dr[j-1][k-1]);
					else dr[j][k] = dr[j-1][k];
				}
				else if(val == 3){
					if(k == 3 || k == 4) dr[j][k] = dr[j-1][k] + 1;
					else if(k == 5) dr[j][k] = min({dr[j-1][3], dr[j-1][4], dr[j-1][5]});
					else dr[j][k] = dr[j-1][k];
				}
				else{
					if(k == 4) dr[j][k] = min(dr[j-1][k] + 1, dr[j-1][k-1]);
					else dr[j][k] = dr[j-1][k];
				}
			}
		}
		for(auto &i : x){
			ret[i.idx] = min(dl[i.s][0] + dr[i.e][4], ret[i.idx]);
		}
	}
}

int main(){
	scanf("%d %d %s",&n,&q,str+1);
	vector<query> v;
	for(int i=0; i<q; i++){
		query qr;
		scanf("%d %d",&qr.s,&qr.e);
		qr.idx = i;
		v.push_back(qr);
	}
	memset(ret, 0x3f, sizeof(ret));
	solve(1, n, v);
	for(int i=0; i<q; i++){
		if(ret[i] > 1e8) ret[i] = -1;
		printf("%d\n", ret[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pi;
typedef long long lint;
const int MAXN = 200005;

struct query{
	int s, e, idx;
};

int n, q, ret[MAXN];
char str[MAXN];
int dl[MAXN][6], dr[MAXN][6];

int code(char c){
	if(c == '2') return 0;
	if(c == '0') return 1;
	if(c == '1') return 2;
	if(c == '6') return 3;
	if(c == '7') return 4;
	return -1;
}

void solve(int s, int e, vector<query> v){
	if(s == e){
		return;
	}
	int m = (s+e)/2;
	vector<query> l, r, x;
	for(auto &i : v){
		if(i.e <= m) l.push_back(i);
		else if(i.s > m) r.push_back(i);
		else x.push_back(i);
	}
	solve(s, m, l);
	solve(m+1, e, r);
	for(int i=0; i<6; i++){
		for(int j=0; j<6; j++){
			dl[m+1][j] = dr[m][j] = 1e9;
		}
		dl[m+1][i] = dr[m][i] = 0;
		for(int j=m; j>=s; j--){
			int val = code(str[j]);
			for(int k=0; k<6; k++){
				if(val == -1){
					dl[j][k] = dl[j+1][k];
				}
				else if(val <= 2){
					if(k == val) dl[j][k] = min(dl[j+1][k] + 1, dl[j+1][k+1]);
					else dl[j][k] = dl[j+1][k];
				}
				else if(val == 3){
					if(k == 3 || k == 4) dl[j][k] = min(dl[j+1][k] + 1, dl[j+1][5]);
					else dl[j][k] = dl[j+1][k];
				}
				else{
					if(k == 3) dl[j][k] = min(dl[j+1][k] + 1, dl[j+1][k+1]);
					else dl[j][k] = dl[j+1][k];
				}
			}
		}
		for(int j=m+1; j<=e; j++){
			int val = code(str[j]);
			for(int k=0; k<6; k++){
				if(val == -1){
					dr[j][k] = dr[j-1][k];
				}
				else if(val <= 2){
					if(k == val+1) dr[j][k] = min(dr[j-1][k], dr[j-1][k-1]);
					else dr[j][k] = dr[j-1][k] + (k == val);
				}
				else if(val == 3){
					if(k == 3 || k == 4) dr[j][k] = dr[j-1][k] + 1;
					else if(k == 5) dr[j][k] = min({dr[j-1][3], dr[j-1][4], dr[j-1][5]});
					else dr[j][k] = dr[j-1][k];
				}
				else{
					if(k == 4) dr[j][k] = min(dr[j-1][k] + 1, dr[j-1][k-1]);
					else dr[j][k] = dr[j-1][k];
				}
			}
		}
		for(auto &i : x){
			ret[i.idx] = min(dl[i.s][0] + dr[i.e][4], ret[i.idx]);
		}
	}
}

int main(){
	scanf("%d %d %s",&n,&q,str+1);
	vector<query> v;
	for(int i=0; i<q; i++){
		query qr;
		scanf("%d %d",&qr.s,&qr.e);
		qr.idx = i;
		v.push_back(qr);
	}
	memset(ret, 0x3f, sizeof(ret));
	solve(1, n, v);
	for(int i=0; i<q; i++){
		if(ret[i] > 1e8) ret[i] = -1;
		printf("%d\n", ret[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pi;
typedef long long lint;
const int MAXN = 200005;

struct query{
	int s, e, idx;
};

int n, q, ret[MAXN];
char str[MAXN];
int dl[MAXN][6], dr[MAXN][6];

int code(char c){
	if(c == '2') return 0;
	if(c == '0') return 1;
	if(c == '1') return 2;
	if(c == '6') return 3;
	if(c == '7') return 4;
	return -1;
}

void solve(int s, int e, vector<query> v){
	if(s == e){
		return;
	}
	int m = (s+e)/2;
	vector<query> l, r, x;
	for(auto &i : v){
		if(i.e <= m) l.push_back(i);
		else if(i.s > m) r.push_back(i);
		else x.push_back(i);
	}
	solve(s, m, l);
	solve(m+1, e, r);
	for(int i=0; i<6; i++){
		for(int j=0; j<6; j++){
			dl[m+1][j] = dr[m][j] = 1e9;
		}
		dl[m+1][i] = dr[m][i] = 0;
		for(int j=m; j>=s; j--){
			int val = code(str[j]);
			for(int k=0; k<6; k++){
				if(val == -1){
					dl[j][k] = dl[j+1][k];
				}
				else if(val <= 2){
					if(k == val) dl[j][k] = min(dl[j+1][k] + 1, dl[j+1][k+1]);
					else dl[j][k] = dl[j+1][k];
				}
				else if(val == 3){
					if(k == 3 || k == 4) dl[j][k] = min(dl[j+1][k] + 1, dl[j+1][5]);
					else dl[j][k] = dl[j+1][k];
				}
				else{
					if(k == 3) dl[j][k] = min(dl[j+1][k] + 1, dl[j+1][k+1]);
					else dl[j][k] = dl[j+1][k];
				}
			}
		}
		for(int j=m+1; j<=e; j++){
			int val = code(str[j]);
			for(int k=0; k<6; k++){
				if(val == -1){
					dr[j][k] = dr[j-1][k];
				}
				else if(val <= 2){
					if(k == val+1) dr[j][k] = min(dr[j-1][k], dr[j-1][k-1]);
					else dr[j][k] = dr[j-1][k] + (k == val);
				}
				else if(val == 3){
					if(k == 3 || k == 4) dr[j][k] = dr[j-1][k] + 1;
					else if(k == 5) dr[j][k] = min({dr[j-1][3], dr[j-1][4], dr[j-1][5]});
					else dr[j][k] = dr[j-1][k];
				}
				else{
					if(k == 4) dr[j][k] = min(dr[j-1][k], dr[j-1][k-1]);
					else dr[j][k] = dr[j-1][k] + (k == 3);
				}
			}
		}
		for(auto &i : x){
			ret[i.idx] = min(dl[i.s][0] + dr[i.e][4], ret[i.idx]);
		}
	}
}

int main(){
	scanf("%d %d %s",&n,&q,str+1);
	vector<query> v;
	for(int i=0; i<q; i++){
		query qr;
		scanf("%d %d",&qr.s,&qr.e);
		qr.idx = i;
		v.push_back(qr);
	}
	memset(ret, 0x3f, sizeof(ret));
	solve(1, n, v);
	for(int i=0; i<q; i++){
		if(ret[i] > 1e8) ret[i] = -1;
		printf("%d\n", ret[i]);
	}
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef long double ld;
typedef unsigned int uint;
#define MAX 200105
bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et() {
    puts("-1"); exit(0);
}

struct node {
    int a[5][5];
    node operator+(const node& o) const {
        node x;
        REP(i,5) REP(j,5) {
            x.a[i][j] = inf9;
            REP(k,5) x.a[i][j] = min(x.a[i][j], a[i][k]+o.a[k][j]);
        }
        return x;
    }
}tr[MAX*4];
char s[MAX];
void build(int rt, int l, int r) {
    if (l==r) {
        REP(i,5) REP(j,5) tr[rt].a[i][j] = i==j ? 0 : inf9;
        if (s[l]=='2') {
            tr[rt].a[0][0]=1; tr[rt].a[0][1]=0;
        } else if (s[l]=='0') {
            tr[rt].a[1][1]=1; tr[rt].a[1][2]=0;
        } else if (s[l]=='1') {
            tr[rt].a[2][2]=1; tr[rt].a[2][3]=0;
        } else if (s[l]=='7') {
            tr[rt].a[3][3]=1; tr[rt].a[3][4]=0;
        } else if (s[l]=='6') {
            tr[rt].a[3][3]=1; tr[rt].a[4][4]=1;
        }
        return;
    }
    int mid = (l+r)/2;
    build(lch,l,mid); build(rch,mid+1,r);
    tr[rt] = tr[lch] + tr[rch];
}
node qy(int rt, int l, int r, int L, int R) {
    if (l==L && R==r) return tr[rt];
    int mid = (l+r)/2;
    if (R<=mid) return qy(lch,l,mid,L,R);
    if (mid<L) return qy(rch,mid+1,r,L,R);
    return qy(lch,l,mid,L,mid) + qy(rch,mid+1,r,mid+1,R);
}
bool fmain(int tid) {
    scanf("%d%d", &n, &k);
    scanf("%s", s+1);
    build(1,1,n);
    REP(i,k) {
        int l,r; scanf("%d%d",&l,&r);
        int z = qy(1, 1, n, l, r).a[0][4];
        if (z==inf9) z=-1;
        printf("%d\n", z);
    }
    return 1;
}
int main() {
    int t=1;// scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <bits/stdc++.h>
#if defined(__GNUC__)
#pragma GCC optimize ("Ofast")
#endif
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef pair<ll, ll> pll;
#define debug(x) cerr<<#x<<'='<<(x)<<endl;
#define debugp(x) cerr<<#x<<"= {"<<(x.first)<<", "<<(x.second)<<"}"<<endl;
#define debug2(x, y) cerr<<"{"<<#x<<", "<<#y<<"} = {"<<(x)<<", "<<(y)<<"}"<<endl;
#define debugv(v) cerr<<#v<<" : ";for (auto x:v) cerr<<x<<' ';cerr<<endl;
#define all(x) x.begin(), x.end()
#define pb push_back
#define kill(x) return cout<<x<<'\n', 0;

const ld eps=1e-7;
const int inf=1e9;
const ll INF=10000000000000010LL;
const int mod = 1000000007;
const int MAXN = 200010, LOG=20;

struct node{
	int M[5][5];
	node(int val=0){
		for (int i=0; i<=4; i++) for (int j=i; j<=4; j++) M[i][j]=inf;
		if (val) for (int i=0; i<=4; i++) M[i][i]=0;
	}
} seg[MAXN<<2];

node combine(node x, node y){
	node out(0);
	for (int i=0; i<=4; i++) for (int j=i; j<=4; j++) for (int k=i; k<=j; k++) out.M[i][j]=min(out.M[i][j], x.M[i][k] + y.M[k][j]);
	return out;
}

int n, m, k, u, v, x, y, t, l, r, ans;
int cnt[MAXN];
int last[MAXN][10];
string s;

node build(int id, int tl, int tr){
	if (tl==tr){
		for (int i=0; i<=4; i++) seg[id].M[i][i]=0;
		if (s[tl]=='2') seg[id].M[0][1]=seg[id].M[0][0]=1;
		if (s[tl]=='0') seg[id].M[1][2]=seg[id].M[1][1]=1;
		if (s[tl]=='1') seg[id].M[2][3]=seg[id].M[2][2]=1;
		if (s[tl]=='6') seg[id].M[3][4]=seg[id].M[3][3]=1;
		return seg[id];
	}
	int mid=(tl+tr)>>1;
	return seg[id]=combine(build(id<<1, tl, mid), build(id<<1 | 1, mid+1, tr));
}

node get(int id, int tl, int tr, int l, int r){
	if (r<tl || tr<l) return node(1);
	if (l<=tl && tr<=r) return seg[id];
	int mid=(tl+tr)>>1;
	return combine(get(id<<1, tl, mid, l, r), get(id<<1 | 1, mid+1, tr, l, r));
}

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin>>n>>m>>s;
	s="."+s;
	build(1, 1, n);
	for (int i=1; i<=n; i++){
		cnt[i]=cnt[i-1] + (s[i]=='6');
		for (int j=0; j<=9; j++) last[i][j]=last[i-1][j];
		last[i][s[i]-'0']=i;
	}

	while (m--){
		cin>>l>>r;
		int pos=r;
		if (pos) pos=last[pos][7];
		if (pos) pos=last[pos][1];
		if (pos) pos=last[pos][0];
		if (pos) pos=last[pos][2];
		if (l>pos){
			cout<<-1<<'\n';
			continue ;
		}
		pos=last[r][7];
		ans=(cnt[r]-cnt[pos]) + get(1, 1, n, l, last[r][7]).M[0][3];
		cout<<ans-3<<'\n';
	}

	return 0;
}


#include <bits/stdc++.h>
#if defined(__GNUC__)
#pragma GCC optimize ("Ofast")
#endif
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef pair<ll, ll> pll;
#define debug(x) cerr<<#x<<'='<<(x)<<endl;
#define debugp(x) cerr<<#x<<"= {"<<(x.first)<<", "<<(x.second)<<"}"<<endl;
#define debug2(x, y) cerr<<"{"<<#x<<", "<<#y<<"} = {"<<(x)<<", "<<(y)<<"}"<<endl;
#define debugv(v) cerr<<#v<<" : ";for (auto x:v) cerr<<x<<' ';cerr<<endl;
#define all(x) x.begin(), x.end()
#define pb push_back
#define kill(x) return cout<<x<<'\n', 0;

const ld eps=1e-7;
const int inf=9;
const ll INF=10000000000000010LL;
const int mod = 1000000007;
const int MAXN = 200010, LOG=20;

struct node{
	int M[5][5];
	node(int val=0){
		for (int i=0; i<=4; i++) for (int j=i; j<=4; j++) M[i][j]=inf;
		if (val) for (int i=0; i<=4; i++) M[i][i]=0;
	}
} seg[MAXN<<2];

node combine(node x, node y){
	node out(0);
	for (int i=0; i<=4; i++) for (int j=i; j<=4; j++) for (int k=i; k<=j; k++) out.M[i][j]=min(out.M[i][j], x.M[i][k] + y.M[k][j]);
	return out;
}

int n, m, k, u, v, x, y, t, l, r, ans;
int cnt[MAXN];
int last[MAXN][10];
string s;

node build(int id, int tl, int tr){
	if (tl==tr){
		for (int i=0; i<=4; i++) seg[id].M[i][i]=0;
		if (s[tl]=='2') seg[id].M[0][1]=seg[id].M[0][0]=1;
		if (s[tl]=='0') seg[id].M[1][2]=seg[id].M[1][1]=1;
		if (s[tl]=='1') seg[id].M[2][3]=seg[id].M[2][2]=1;
		if (s[tl]=='6') seg[id].M[3][4]=seg[id].M[3][3]=1;
		return seg[id];
	}
	int mid=(tl+tr)>>1;
	return seg[id]=combine(build(id<<1, tl, mid), build(id<<1 | 1, mid+1, tr));
}

node get(int id, int tl, int tr, int l, int r){
	if (r<tl || tr<l) return node(1);
	if (l<=tl && tr<=r) return seg[id];
	int mid=(tl+tr)>>1;
	return combine(get(id<<1, tl, mid, l, r), get(id<<1 | 1, mid+1, tr, l, r));
}

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin>>n>>m>>s;
	s="."+s;
	build(1, 1, n);
	for (int i=1; i<=n; i++){
		cnt[i]=cnt[i-1] + (s[i]=='6');
		for (int j=0; j<=9; j++) last[i][j]=last[i-1][j];
		last[i][s[i]-'0']=i;
	}

	while (m--){
		cin>>l>>r;
		int pos=r;
		if (pos) pos=last[pos][7];
		if (pos) pos=last[pos][1];
		if (pos) pos=last[pos][0];
		if (pos) pos=last[pos][2];
		if (l>pos){
			cout<<-1<<'\n';
			continue ;
		}
		pos=last[r][7];
		ans=(cnt[r]-cnt[pos]) + get(1, 1, n, l, last[r][7]).M[0][3];
		cout<<ans-3<<'\n';
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const LL N = 1234567;
const LL inf = 1e9;

inline LL read()
{
  LL p=0; LL f=1; char ch=getchar();
  while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
  while(ch>='0' && ch<='9'){p=p*10+(ch-'0'); ch=getchar();}
  return p*f;
}

struct node
{
  LL a[5][5];
  node(){memset(a,63,sizeof(a));}
  friend node operator + (node x,node y)
  {
    node z;
    for(LL i=0;i<=4;i++) for(LL j=0;j<=4;j++) for(LL k=0;k<=4;k++)
      z.a[i][j] = min(z.a[i][j] , x.a[i][k] + y.a[k][j]);
    return z;
  }
};

LL n,q; char ss[N<<1];

LL lc[N],rc[N],rt,tot; node C[N];

void link(LL &u,LL L,LL R,LL k,node c)
{
  if(!u) u=++tot;
  if(L==R){C[u] = c; return ;}
  LL mid=(L+R)>>1;
  if(k<=mid) link(lc[u],L,mid,k,c);
  else link(rc[u],mid+1,R,k,c);
  C[u] = C[lc[u]] + C[rc[u]];
}

node qry(LL u,LL L,LL R,LL l,LL r)
{
  if(L==l && R==r) return C[u];
  LL mid=(L+R)>>1;
  if(r<=mid) return qry(lc[u],L,mid,l,r);
  else if(l>mid) return qry(rc[u],mid+1,R,l,r);
  else return qry(lc[u],L,mid,l,mid) + qry(rc[u],mid+1,R,mid+1,r);
}

int main()
{

  n=read(); q=read();
  for(LL i=1;i<=n;i++) scanf("\n%c",&ss[i]);

  rt=tot=0; node p; memset(p.a,63,sizeof(p.a));
  for(LL j=0;j<=4;j++) p.a[j][j] = 0;
  for(LL i=1;i<=n;i++) if(ss[i] != '2' && ss[i] != '0' && ss[i] != '7' && ss[i] !='6' && ss[i] != '1') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(LL j=0;j<=4;j++) p.a[j][j] = 0; p.a[0][1] = 0; p.a[0][0] = 1;
  for(LL i=1;i<=n;i++) if(ss[i] == '2') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(LL j=0;j<=4;j++) p.a[j][j] = 0; p.a[1][2] = 0; p.a[1][1] = 1;
  for(LL i=1;i<=n;i++) if(ss[i] == '0') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(LL j=0;j<=4;j++) p.a[j][j] = 0; p.a[2][3] = 0; p.a[2][2] = 1;
  for(LL i=1;i<=n;i++) if(ss[i] == '1') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(LL j=0;j<=4;j++) p.a[j][j] = 0; p.a[3][4] = 0; p.a[3][3] = 1;
  for(LL i=1;i<=n;i++) if(ss[i] == '7') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(LL j=0;j<=4;j++) p.a[j][j] = 0; p.a[3][3] = 1; p.a[4][4] = 1;
  for(LL i=1;i<=n;i++) if(ss[i] == '6') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a)); p.a[0][0] = 0;
  while(q--)
  {
    LL l=read(); LL r=read();
    node ans = p+ qry(rt,1,n,l,r) ;
    printf("%lld\n",(ans. a[0][4] > inf) ? (-1) : ans.a[0][4]) ;
  }

  return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 800010;
const int inf = 1e9;

inline int read()
{
  int p=0; int f=1; char ch=getchar();
  while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
  while(ch>='0' && ch<='9'){p=p*10+(ch-'0'); ch=getchar();}
  return p*f;
}

struct node
{
  int a[5][5];
  node(){memset(a,63,sizeof(a));}
  friend node operator + (node x,node y)
  {
    node z;
    for(int i=0;i<=4;i++) for(int j=0;j<=4;j++) for(int k=0;k<=4;k++)
      z.a[i][j] = min(z.a[i][j] , x.a[i][k] + y.a[k][j]);
    return z;
  }
};

int n,q; char ss[N<<1];

int lc[N],rc[N],rt,tot; node C[N];

void link(int &u,int L,int R,int k,node c)
{
  if(!u) u=++tot;
  if(L==R){C[u] = c; return ;}
  int mid=(L+R)>>1;
  if(k<=mid) link(lc[u],L,mid,k,c);
  else link(rc[u],mid+1,R,k,c);
  C[u] = C[lc[u]] + C[rc[u]];
}

node qry(int u,int L,int R,int l,int r)
{
  if(L==l && R==r) return C[u];
  int mid=(L+R)>>1;
  if(r<=mid) return qry(lc[u],L,mid,l,r);
  else if(l>mid) return qry(rc[u],mid+1,R,l,r);
  else return qry(lc[u],L,mid,l,mid) + qry(rc[u],mid+1,R,mid+1,r);
}

int main()
{

  n=read(); q=read();
  for(int i=1;i<=n;i++) scanf("\n%c",&ss[i]);

  rt=tot=0; node p; memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0;
  for(int i=1;i<=n;i++) if(ss[i] != '2' && ss[i] != '0' && ss[i] != '7' && ss[i] !='6' && ss[i] != '1') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[0][1] = 0; p.a[0][0] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '2') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[1][2] = 0; p.a[1][1] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '0') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[2][3] = 0; p.a[2][2] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '1') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[3][4] = 0; p.a[3][3] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '7') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[3][3] = 1; p.a[4][4] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '6') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a)); p.a[0][0] = 0;
  while(q--)
  {
    int l=read(); int r=read();
    node ans = p+ qry(rt,1,n,l,r) ;
    printf("%lld\n",(ans. a[0][4] > inf) ? (-1) : ans.a[0][4]) ;
  }

  return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 800010;
const int inf = 1e9;

inline int read()
{
  int p=0; int f=1; char ch=getchar();
  while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
  while(ch>='0' && ch<='9'){p=p*10+(ch-'0'); ch=getchar();}
  return p*f;
}

struct node
{
  int a[5][5];
  node(){memset(a,63,sizeof(a));}
  friend node operator + (node x,node y)
  {
    node z;
    for(int i=0;i<=4;i++) for(int j=0;j<=4;j++) for(int k=0;k<=4;k++)
      z.a[i][j] = min(z.a[i][j] , x.a[i][k] + y.a[k][j]);
    return z;
  }
};

int n,q; char ss[N<<1];

int lc[N],rc[N],rt,tot; node C[N];

void link(int &u,int L,int R,int k,node c)
{
  if(!u) u=++tot;
  if(L==R){C[u] = c; return ;}
  int mid=(L+R)>>1;
  if(k<=mid) link(lc[u],L,mid,k,c);
  else link(rc[u],mid+1,R,k,c);
  C[u] = C[lc[u]] + C[rc[u]];
}

node qry(int u,int L,int R,int l,int r)
{
  if(L==l && R==r) return C[u];
  int mid=(L+R)>>1;
  if(r<=mid) return qry(lc[u],L,mid,l,r);
  else if(l>mid) return qry(rc[u],mid+1,R,l,r);
  else return qry(lc[u],L,mid,l,mid) + qry(rc[u],mid+1,R,mid+1,r);
}

int main()
{

  n=read(); q=read();
  for(int i=1;i<=n;i++) scanf("\n%c",&ss[i]);

  rt=tot=0; node p; memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0;
  for(int i=1;i<=n;i++) if(ss[i] != '2' && ss[i] != '0' && ss[i] != '7' && ss[i] !='6' && ss[i] != '1') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[0][1] = 0; p.a[0][0] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '2') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[1][2] = 0; p.a[1][1] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '0') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[2][3] = 0; p.a[2][2] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '1') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[3][4] = 0; p.a[3][3] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '7') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a));
  for(int j=0;j<=4;j++) p.a[j][j] = 0; p.a[3][3] = 1; p.a[4][4] = 1;
  for(int i=1;i<=n;i++) if(ss[i] == '6') link(rt,1,n,i,p);

  memset(p.a,63,sizeof(p.a)); p.a[0][0] = 0;
  while(q--)
  {
    int l=read(); int r=read();
    node ans = p+ qry(rt,1,n,l,r) ;
    printf("%d\n",(ans. a[0][4] > inf) ? (-1) : ans.a[0][4]) ;
  }

  return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-6;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=1e7+9;
const int MAXN=200005;
const int MX=1e7+50;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
int n,Case;
char st[MAXN];
struct Matrix
{
	int A[5][5];
	Matrix(int n1=0) { n=n1; memset(A,INF,sizeof A); }
	Matrix operator +(const Matrix &b)
	{
		Matrix ans(5);
		for (int i=0;i<5;i++)
			for (int j=0;j<5;j++)
				for (int k=0;k<5;k++) upmin(ans.A[i][j],A[i][k]+b.A[k][j]);
		return ans;
	}
	void print()
	{
		for (int i=0;i<5;i++)
		{
			for (int j=0;j<5;j++) cout<<setw(5)<<(A[i][j]==INF?-1:A[i][j]);
			cout<<endl;
		}
	}
} s[MAXN<<2];
Matrix get(char c)
{
	Matrix ans(5);
	for (int i=0;i<5;i++) ans.A[i][i]=0;
	if (c=='2') ans.A[0][0]=1,ans.A[0][1]=0;
	if (c=='0') ans.A[1][1]=1,ans.A[1][2]=0;
	if (c=='1') ans.A[2][2]=1,ans.A[2][3]=0;
	if (c=='7') ans.A[3][3]=1,ans.A[3][4]=0;
	if (c=='6') ans.A[3][3]=1,ans.A[4][4]=1;
	return ans;
}
Matrix query(int x,int l,int r,int L,int R)
{
	if (l>=L&&r<=R) return s[x];
	int mid=(l+r)>>1;
	if (R<=mid) return query(x<<1,l,mid,L,R);
	else if (L>mid) return query(x<<1|1,mid+1,r,L,R);
	else return query(x<<1,l,mid,L,mid)+query(x<<1|1,mid+1,r,mid+1,R);
}
void build(int x,int l,int r)
{
	if (l==r) { s[x]=get(st[l]); return; }
	int mid=(l+r)>>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	s[x]=s[x<<1]+s[x<<1|1];
}
signed main()
{
	int n=read(),Case=read();
	scanf("%s",st+1);
	build(1,1,n);
	while (Case--)
	{
		int l=read(),r=read();
		Matrix ans=query(1,1,n,l,r);
		printf("%d\n",ans.A[0][4]==INF?-1:ans.A[0][4]);
	}
	return 0;
}