import java.util.*;

import javax.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener;

import java.io.*;

public class A {
	static BufferedReader br;
	static PrintWriter pw;
	static int inf = (int) 1e9;
	static long mod = (long) 1e9 + 7;

	static ArrayList<Integer>[] graph;
	static int n;
	static char[][] a;
	static boolean[][] vis;

	public static void main(String[] args) throws NumberFormatException, IOException, InterruptedException {
//		br = new BufferedReader(new FileReader(new File("chief.in")));
//		br = new BufferedReader(new InputStreamReader(System.in));
		Scanner sc = new Scanner(System.in);
		pw = new PrintWriter(System.out);
		int t = sc.nextInt();
		while (t-- > 0) {
			n = sc.nextInt();
			a = new char[n][n];
			for (int i = 0; i < a.length; i++) {
				a[i] = sc.nextLine().toCharArray();
			}
			int c = 0;
			ArrayList<pair> ans = new ArrayList<>();
			if (a[n - 1][n - 2] == '0') {
				ans.add(new pair(n, n - 1));
				c++;
			}
			if (a[n - 2][n - 1] == '0') {
				ans.add(new pair(n - 1, n));
				c++;
			}
			if (a[1][0] == '1') {
				ans.add(new pair(2, 1));
				c++;
			}
			if (a[0][1] == '1') {
				ans.add(new pair(1, 2));
				c++;
			}
			if(c<3) {
			pw.println(c);
			for (pair x : ans)
				pw.println(x.x + " " + x.y);
			}
			else {
				c=0;
				ans=new ArrayList<>();
				if (a[n - 1][n - 2] == '1') {
					ans.add(new pair(n, n - 1));
					c++;
				}
				if (a[n - 2][n - 1] == '1') {
					ans.add(new pair(n - 1, n));
					c++;
				}
				if (a[1][0] == '0') {
					ans.add(new pair(2, 1));
					c++;
				}
				if (a[0][1] == '0') {
					ans.add(new pair(1, 2));
					c++;
				}
				pw.println(c);
				for (pair x : ans)
					pw.println(x.x + " " + x.y);
			}
//			vis = new boolean[n][n];
//			boolean f = find('0', 0, 0);
//			vis = new boolean[n][n];
//			boolean g = find('1', 0, 0);
////			System.out.println(f+" "+g);
//			if (!f && !g)
//				c = 0;
//			else if (f && g) {
//				c = 2;
//				if (a[n - 1][n - 2] == '0') {
//					ans.add(new pair(n, n - 1));
//				}
//				if (a[n - 2][n - 1] == '0') {
//					ans.add(new pair(n - 1, n));
//				}
//				if (a[1][0] == '1') {
//					ans.add(new pair(2, 1));
//				}
//				if (a[0][1] == '1') {
//					ans.add(new pair(1, 2));
//				}
//			} else if (f) {
//				if (a[0][1] == '0' && a[1][0] == '0') {
//					if (a[n - 1][n - 2] == '0') {
//						c++;
//						ans.add(new pair(n, n - 1));
//					}
//					if (a[n - 2][n - 1] == '0') {
//						c++;
//						ans.add(new pair(n - 1, n));
//					}
//				} else {
//
//				}
//			} else {
//				if (a[0][1] == '1' && a[1][0] == '1') {
//					if (a[n - 1][n - 2] == '1') {
//						c++;
//						ans.add(new pair(n, n - 1));
//					}
//					if (a[n - 2][n - 1] == '1') {
//						c++;
//						ans.add(new pair(n - 1, n));
//					}
//				}
//			}
		}

		pw.flush();
		pw.close();

	}

	static boolean find(int s, int x, int y) {
		vis[x][y] = true;
		if (valid(x, y)) {
			if (x == n - 1 && y == n - 1)
				return true;
			boolean f = false;
			if (valid(x - 1, y) && !vis[x - 1][y] && (a[x - 1][y] == s || a[x - 1][y] == 'F'))
				f |= find(s, x - 1, y);
			if (valid(x + 1, y) && !vis[x + 1][y] && (a[x + 1][y] == s || a[x + 1][y] == 'F'))
				f |= find(s, x + 1, y);
			if (valid(x, y + 1) && !vis[x][y + 1] && (a[x][y + 1] == s || a[x][y + 1] == 'F'))
				f |= find(s, x, y + 1);
			if (valid(x, y - 1) && !vis[x][y - 1] && (a[x][y - 1] == s || a[x][y - 1] == 'F'))
				f |= find(s, x, y - 1);
			return f;
		}
		return false;
	}

	static boolean valid(int x, int y) {
		return x > -1 && x < n && y > -1 && y < n;
	}

	static long ans;
	static long[][] dp;
	static boolean[] color, down, total;

	static int dfs(int u, int pa) {
		int sum = down[u] ? 1 : 0;
		for (int v : graph[u]) {
			if (v == pa)
				continue;
			int s = dfs(v, u);
			ans += Math.min((2 * k - s), s);
			sum += s;
		}
		return sum;
	}

//	static int dfs2(int u, int pa, long l) {
//		int sum = 0;
//		for (pair v : graph[u]) {
//			if (v.x == pa)
//				continue;
//			if (l + v.y > down[v.x]) {
//				sum += total[v.x];
//			} else {
//				sum += dfs2(v.x, u, Math.max(0, l + v.y));
//			}
//		}
//		return sum;
//	}

//	static long[] f, g;
//
//	static void numOfSubtrees(int u, int pa) {
//		f[u] = 1;
//		for (int v : graph[u]) {
//			if (v == pa)
//				continue;
//			numOfSubtrees(v, u);
//			f[u] *= (1 + f[v]);
//			g[u] += f[v] + g[v];
//		}
//	}

	static ArrayList<Integer> primes; // generated by sieve

	/*
	 * 1. Generating a list of prime factors of N
	 */
	static ArrayList<Long> primeFactors(Long N) // O(sqrt(N) / ln sqrt(N))
	{
		ArrayList<Long> factors = new ArrayList<Long>(); // take abs(N) in case of -ve integers
		int idx = 0, p = primes.get(idx);

		while (p * p <= N) {
			if (N % p == 0)
				factors.add((long) p);
			while (N % p == 0) {
				N /= p;
			}
			if (idx + 1 == primes.size())
				break;
			p = primes.get(++idx);
		}

		if (N != 1) // last prime factor may be > sqrt(N)
			factors.add(N); // for integers whose largest prime factor has a power of 1
		return factors;
	}

	static int[] isComposite;

	static void sieve(int N) // O(N log log N)
	{
		isComposite = new int[N + 1];
		isComposite[0] = isComposite[1] = 1; // 0 indicates a prime number
		primes = new ArrayList<Integer>();

		for (int i = 2; i <= N; ++i) // can loop till i*i <= N if primes array is not needed O(N log log sqrt(N))
			if (isComposite[i] == 0) // can loop in 2 and odd integers for slightly better performance
			{
				primes.add(i);
				if (1l * i * i <= N)
					for (int j = i * i; j <= N; j += i) // j = i * 2 will not affect performance too much, may alter in
														// modified sieve
						isComposite[j] = 1;
			}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

	}

	static int m, k;

	static double[] memo;
	static ArrayList<Integer>[] adj;

	static long gcd(long a, long b) {
		if (a == 0)
			return b;
		return gcd(b % a, a);
	}

	// method to return LCM of two numbers
	static long lcm(long a, long b) {
		return (a * b) / gcd(a, b);
	}

	static double dis(int x, int y, int z, int w) {
		return Math.sqrt((x - z) * (x - z) + (y - w) * (y - w));
	}

	static int[] nxtarr() throws IOException {
		StringTokenizer st = new StringTokenizer(br.readLine());
		int[] a = new int[st.countTokens()];
		for (int i = 0; i < a.length; i++) {
			a[i] = Integer.parseInt(st.nextToken());
		}
		return a;
	}

	static long[] nxtarrLong() throws IOException {
		StringTokenizer st = new StringTokenizer(br.readLine());
		long[] a = new long[st.countTokens()];
		for (int i = 0; i < a.length; i++) {
			a[i] = Long.parseLong(st.nextToken());
		}
		return a;
	}

	static class pair implements Comparable<pair> {
		int x;
		int y;

		public pair(int d, int u) {
			x = d;
			y = u;
		}

		@Override
		public int compareTo(pair o) {
			// TODO Auto-generated method stub
			if (y == o.y)
				return x - o.x;
			return y - o.y;
		}

	}

	static class triple implements Comparable<triple> {
		int x;
		int y;
		int z;

		public triple(int a, int b, int c) {
			x = a;
			y = b;
			z = c;
		}

		@Override
		public int compareTo(triple o) {
			// TODO Auto-generated method stub
			return x - o.x;
		}
	}

}
