// Arup Guha
// 11/9/2010
// Solution to 2010 SE Regional Problem E: Maximum Square

import java.util.*;

public class e {
	
	public int[][] grid;
	public int[][] sumrows;
	public int[][] sumcols;
	public int best;

	public static void main(String[] args) {
		
		Scanner stdin = new Scanner(System.in);
		
		int row, col;
		row = stdin.nextInt();
		col = stdin.nextInt();
		
		while (row!=0 && col!=0) {
			
			e mygrid = new e(row, col, stdin);
			mygrid.solve();
			System.out.println(mygrid.best);
			
			// Get next case.
			row = stdin.nextInt();
			col = stdin.nextInt();
		}
	}	
	
	// Reads in data into grid and calculates intermediate sums of rows and cols.
	public e(int row, int col, Scanner stdin) {
		
		// Allocate space for all of these.
		grid = new int[row][col];
		sumrows = new int[row][col+1];
		sumcols = new int[row+1][col];
		
		best = 0;
		
		// Sets up sums for 0 terms.
		for (int i=0; i<sumrows.length; i++) 
			sumrows[i][0] = 0;
		for (int i=0; i<sumcols[0].length; i++)
			sumcols[0][i] = 0;
		
		
		// Go through each item.
		for (int i=0; i<grid.length; i++) {
			for (int j=0; j<grid[i].length; j++) {
				grid[i][j] = stdin.nextInt();
		
				// Just get this done. It's simple.
				if (grid[i][j] == 1)
					best = 1;
							
				sumrows[i][j+1] = sumrows[i][j] + grid[i][j];
				sumcols[i+1][j] = sumcols[i][j] + grid[i][j];
			}
		}
	}	
		
	public void solve() {
		
		// If this is true, then no 1 was ever found, skip the work...
		if (best == 0) return;
		
		// Try each starting spot as the top, left spot for the best square.
		for (int i=0; i<grid.length; i++) 
			for (int j=0; j<grid[i].length; j++) 
				findbest(i, j);		
	}
	
	public void findbest(int startrow, int startcol) {
		
		/* See if we can do best first. */
		
		// Impossible to beat what we have.
		if (startrow+best > grid.length || startcol+best > grid[0].length || grid[startrow][startcol] == 0)
			return;
			
		// Just establish THIS SQUARE of best x best.
		for (int i=startrow; i<startrow+best; i++) {
			
			// See if each row here adds to best, exactly.
			// if not, we don't have a best x best square.
			if (sumrows[i][startcol+best] - sumrows[i][startcol] != best)
				return;
		}
		
		// If we get here, we do have a best x best square. Let's "grow" it =)
		while (grow(startrow, startcol));
	}
	
	// Note: best already stores the size of the square!
	public boolean grow(int startrow, int startcol) {
		
		// Can't grow this square because we've run out of room.
		if (startrow+best+1 > grid.length || startcol+best+1 > grid[0].length)
			return false;
			
		// Try adding a row on the bottom.
		if (sumrows[startrow+best][startcol+best+1] - sumrows[startrow+best][startcol] != best+1)
			return false;
		if (sumcols[startrow+best+1][startcol+best] - sumcols[startrow][startcol+best] != best+1)
			return false;
			
		best++;
		return true;
		
	}
		
}