// Arup Guha
// 3/5/2022
// Solution to 2022 UCF HS Contest Problem: Monkey Madness

import java.util.*;

public class monkey {

	public static int r;
	public static int c;
	public static char[][] grid;
	public static int zeroCnt;
	
	final public static int[] DX = {-1,0,0,1};
	final public static int[] DY = {0,-1,1,0};
	
	public static void main(String[] args) {
	
		Scanner stdin = new Scanner(System.in);
		int nC = stdin.nextInt();
		
		// Process cases.
		for (int loop=0; loop<nC; loop++) {
		
			// Read the grid, count monkeys.
			r = stdin.nextInt();
			c = stdin.nextInt();
			grid = new char[r][];
			zeroCnt = 0;
			for (int i=0; i<r; i++) {
				grid[i] = stdin.next().toCharArray();
				for (int j=0; j<c; j++)
					if (grid[i][j] == '0')
						zeroCnt++;
			}
			
			// Just try each # in order.
			int res = -1;
			for (char i='1'; i<='9'; i++) {
				if (bfs(i)) {
					res = i-'0';
					break;
				}
			}
			
			// Ta da!
			System.out.println(res);
		}
	}
	
	public static boolean bfs(char limit) {
	
		boolean[][] used = new boolean[r][c];
		LinkedList<Integer> q = new LinkedList<Integer>();
		
		// Add first and last rows.
		for (int i=0; i<c; i++) {
			if (grid[0][i] <= limit) {
				q.offer(i);
				used[0][i] = true;
			}
			if (grid[r-1][i] <= limit) {
				q.offer((r-1)*c + i);
				used[r-1][i] = true;
			}
		}
		
		// Add first and last columns.
		for (int i=1; i<r-1; i++) {
			if (grid[i][0] <= limit) {
				q.offer(i*c);
				used[i][0] = true;
			}
			if (grid[i][c-1] <= limit) {
				q.offer(i*c + c-1);
				used[i][c-1] = true;
			}
		}
		
		int found = 0;
			
		// Run BFS.
		while (q.size() > 0) {
		
			// Get next item.
			int cur = q.poll();
			int curX = cur/c;
			int curY = cur%c;
				
			// Try all neighbors.
			for (int i=0; i<DX.length; i++) {
			
				// Here is the neighbor.
				int nX = curX + DX[i];
				int nY = curY + DY[i];
				
				// Three reasons not to process this one (out of bounds, been there or too high).
				if (!inbounds(nX, nY)) continue;
				if (used[nX][nY]) continue;
				if (grid[nX][nY] > limit) continue;
				
				// Add to queue, add to zero count, if necessary.
				if (grid[nX][nY] == '0') found++;
				used[nX][nY] = true;
				q.offer(nX*c + nY);
			}			
		}
		
		// This is success.
		return found == zeroCnt;
	}
	
	// Returns true iff (myx, myy) is inbounds.
	public static boolean inbounds(int myx, int myy) {
		return myx >= 0 && myx < r && myy >= 0 && myy < c;
	}
}
