n  = int(input())
M = []
for _ in range(n):
    M.append(list(map(int, input().split())))
max_len = 0

def dfs_r(x,y,max_r):  # 寻找右边界
    if y < n:
        if M[x][y] == 0:
            return max_r,y
        return dfs_r(x, y+1,max_r+1)
    else:
        return max_r,y-1
def dfs_b(x,y,max_b): # 寻找下边界
    if x < n:
        if M[x][y] == 0:
            return max_b,x
        return dfs_b(x+1,y,max_b+1)
    else:
        return max_b,x-1

for i in range(n):
    for j in range(n):
        if M[i][j] == 1: # 遍历得到右边界和下边界以及对应最长长度
            max_r,iy = dfs_r(i, j+1, 1)
            max_b,ix = dfs_b(i+1, j, 1)
        else:
            continue
        # 从得到的边界处继续寻找右边界和下边界,看能否构成完整的正方形
        if max_r >= max_b: # 取下边界和右边界中较小的作为正方形边长
            sub = max_r - max_b
            index = iy - sub # 较长的边界需要重新更新位置,右边长,更新右边界iy
            max_temp = max_b
            if dfs_r(ix, j+1, 1)[0] >= max_temp and dfs_b(i+1, index, 1)[0] >= max_temp: # 根据边界点继续向下向右找边界长度
                max_len = max(max_len,max_temp)
        else:
            sub = max_b - max_r
            index = ix - sub # 下边长,更新下边界ix
            max_temp = max_r 
            if dfs_r(index, j+1, 1)[0] >= max_temp and dfs_b(i+1, iy, 1)[0] >= max_temp:# 根据边界点继续向下向右找边界长度
                max_len = max(max_len,max_temp) # 得到最大边长
print(max_len)