#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i)) #define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i)) #define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i)) #if defined(_MSC_VER) || __cplusplus > 199711L #define aut(r,v) auto r = (v) #else #define aut(r,v) __typeof(v) r = (v) #endif #define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it) #define all(o) (o).begin(), (o).end() #define pb(x) push_back(x) #define mp(x,y) make_pair((x),(y)) #define mset(m,v) memset(m,v,sizeof(m)) #define INF 0x3f3f3f3f #define INFL 0x3f3f3f3f3f3f3f3fLL using namespace std; typedef vector vi; typedef pair pii; typedef vector > vpii; typedef long long ll; template inline void amin(T &x, U y) { if(y < x) x = y; } template inline void amax(T &x, U y) { if(x < y) x = y; } struct UnionFind { vector data; void init(int n) { data.assign(n, -1); } bool unionSet(int x, int y) { x = root(x); y = root(y); if(x != y) { if(data[y] < data[x]) swap(x, y); data[x] += data[y]; data[y] = x; } return x != y; } bool findSet(int x, int y) { return root(x) == root(y); } int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); } int size(int x) { return -data[root(x)]; } }; int N, M; UnionFind uf; vector cnt; void process(int i, int j) { if(cnt[i][j] != 0) return; static const int dy[4] = { 0, 1, 0, -1 }, dx[4] = { 1, 0, -1, 0 }; for(int d = 0; d < 4; ++ d) { int yy = i + dy[d], xx = j + dx[d]; if(yy < 0) { uf.unionSet(i * M + j, N * M); continue; } if(yy >= N) { uf.unionSet(i * M + j, N * M + 1); continue; } if(yy < 0 || yy >= N || xx < 0 || xx >= M) continue; if(cnt[yy][xx] != 0) continue; uf.unionSet(i * M + j, yy * M + xx); } }; int main() { int T; scanf("%d", &T); for(int ii = 0; ii < T; ++ ii) { scanf("%d%d", &N, &M); cnt.assign(N, vi(M)); rep(i, N) { char buf[501]; scanf("%s", buf); rep(j, M) cnt[i][j] = buf[j] - '0'; } int Q; scanf("%d", &Q); vector X(Q); vector Y(Q); for(int i = 0; i < Q; ++ i) scanf("%d%d", &X[i], &Y[i]); rep(i, Q) ++ cnt[X[i]][Y[i]]; uf.init(N * M + 2); rep(i, N) rep(j, M) process(i, j); int ans = Q; if(!uf.findSet(N * M, N * M + 1)) { for(-- ans; ans >= 0; -- ans) { -- cnt[X[ans]][Y[ans]]; process(X[ans], Y[ans]); if(uf.findSet(N * M, N * M + 1)) break; } } printf("%d\n", ans == Q ? -1 : ans + 1); } return 0; }