Title: Largest Square

Given a matrix (H x W) containing only 1s and 0s, find the area of the largest square matrix containing only 0s.

Input:
H W
c1,1 c1,2 ... c1,W
c2,1 c2,2 ... c2,W
...
cH,1 cH,2 ... cH,W

In the first line, two integers H and W separated by a space are given. In the following H lines, elements of the H x W matrix are given.

Output:
Print the area (number of 0s) of the largest square.

Constraints:
1 <= H, W <= 1,400

Sample Input:
4 5
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0
0 0 0 1 0

Sample Output:
4

# Buggy version:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
4 5
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0
0 0 0 1 0

output:
4
"""
import sys


def solve():
    dp = [[0] * W for _ in range(H)]
    max_width = 0

    # for m in range(H):
    #     for n in range(W):
    #         print(m, n, carpet_info[m][n])
    #         dp[m][n] = (int(carpet_info[m][n]) + 1) % 2
    #         max_width |= dp[m][n]

    for i in range(1, H):
        for j in range(1, W):
            if not int(carpet_info[i][j]):
                dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1
                max_width = max(max_width, dp[i][j])

    return max_width


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    H, W = map(int, _input[0].split())
    carpet_info = list(map(lambda x: x.split(), _input[1:]))
    print(solve())

# Fixed version:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
4 5
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0
0 0 0 1 0

output:
4
"""
import sys


def solve():
    dp = [[0] * (W + 1) for _ in range(H + 1)]

    for i in range(H):
        for j in range(W):
            if not int(carpet_info[i][j]):
                dp[i + 1][j + 1] = min(dp[i][j], dp[i][j + 1], dp[i + 1][j]) + 1

    max_width = max(map(max, dp))
    return pow(max_width, 2)


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    H, W = map(int, _input[0].split())
    carpet_info = list(map(lambda x: x.split(), _input[1:]))
    print(solve())

# Buggy version:
H,W = map(int,input().split())
tile = [[0 for i in range(W)] for i in range(H)]
buf = [[1 for i in range(W)] for i in range(H)]
maxsquare = 0

for i in range(H):
    tile[i] = list(map(int,input().split()))

for i in range(1,H):
    for j in range(1,W):
        if tile[i][j]!=1:
            if tile[i-1][j]==1 or tile[i][j-1]==1 or tile[i-1][j-1]==1:
                buf[i][j] = 1
            elif tile[i-1][j]==tile[i][j-1]:
                buf[i][j] = buf[i-1][j-1]+1
            else:
                buf[i][j] = min(buf[i-1][j] , buf[i][j-1])+1

            if buf[i][j] > maxsquare:
                maxsquare = buf[i][j]

for i in buf:
    print(i)

print(maxsquare**2)

# Fixed version:
H,W = map(int,input().split())
tile = [[0 for i in range(W)] for i in range(H)]
buf = [[0 for i in range(W+1)] for i in range(H+1)]
maxsquare = 0

for i in range(H):
    tile[i] = list(map(int,input().split()))

for i in range(1,H+1):
    for j in range(1,W+1):
        if tile[i-1][j-1]!=1:
            buf[i][j] = min(buf[i-1][j],buf[i][j-1],buf[i-1][j-1]) + 1

            if buf[i][j] > maxsquare:
                maxsquare = buf[i][j]

print(maxsquare**2)

# Buggy version:
import sys
h, w = map(int, sys.stdin.readline().split())
dp = [[0] * w for _ in range(h)]
G = [list(map(int, i.split())) for i in sys.stdin.readlines()]
for x in range(h):
    dp[x][0] = 1 if G[x][0] == 0 else 0
for y in range(w):
    dp[0][y] = 1 if G[0][y] == 0 else 0
for i in range(1, h):
    for j in range(1, w):
        if(G[i][j] == 0):
            dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1
print(max(sum(dp, []) ** 2))

# Fixed version:
import sys
import itertools
h, w = map(int, sys.stdin.readline().split())
dp = [[0] * w for _ in range(h)]
G = [[int(j) for j in sys.stdin.readline().split()] for _ in range(h)]
for x in range(h):
    dp[x][0] = 1 if G[x][0] == 0 else 0
for y in range(w):
    dp[0][y] = 1 if G[0][y] == 0 else 0
for i in range(1, h):
    for j in range(1, w):
        if(G[i][j] == 0):
            dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1
print(max(max(i) for i in dp) ** 2)

# Buggy version:
# -*- coding: utf-8 -*-
'''
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_3_A&lang=jp
???????¨???????
?????§??£?????¢
'''

H, W = map(int, input().split())
C = list()
maxWidth = 0

for h in range(H):
    C.append(list(map(int, input().split())))

dp = dict()
for h in range(H+1):
    dp[(h, 0)] = 0

for w in range(W+1):
    dp[(0, w)] = 0

for h in range(1, H+1):
    for w in range(1, W+1):
        if C[h-1][w-1] == 1:
            dp[(h, w)] = 0
        else:
            dp[(h, w)] = min(dp[(h-1, w-1)], dp[(h-1, w)], dp[(h, w-1)]) + 1
            maxWidth = max(dp[(h, w)], maxWidth)

print(maxWidth)

# Fixed version:
# -*- coding: utf-8 -*-
'''
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_3_A&lang=jp
???????¨???????
?????§??£?????¢
'''

H, W = map(int, input().split())
C = list()
maxWidth = 0

for h in range(H):
    C.append(list(map(int, input().split())))

dp = dict()
for h in range(H+1):
    dp[(h, 0)] = 0

for w in range(W+1):
    dp[(0, w)] = 0

for h in range(1, H+1):
    for w in range(1, W+1):
        if C[h-1][w-1] == 1:
            dp[(h, w)] = 0
        else:
            dp[(h, w)] = min(dp[(h-1, w-1)], dp[(h-1, w)], dp[(h, w-1)]) + 1
            maxWidth = max(dp[(h, w)], maxWidth)

print(maxWidth**2)

# Buggy version:
h, w = map(int, input().split())
mp = []
for _ in range(h):
  lst = list(map(int, input().split()))
  cum = []
  acc = 0
  for i in lst:
    if i == 0:
      acc += 1
    else:
      acc = 0
    cum.append(acc)
  mp.append(cum)
mp.append([-1] * w)

ans = 0
for x in range(w - 1, -1, -1):
  score_stack = []
  ind_stack = []
  for y in range(h + 1):
#    print(score_stack, ind_stack)
    score = mp[y][x]
    if score_stack == []:
      score_stack.append(score)
      ind_stack.append(y)
    else:
      last_score = score_stack[-1]
      if last_score < score:
        score_stack.append(score)
        ind_stack.append(y)

      elif last_score == score:
        continue

      else:
        while score_stack != [] and score_stack[-1] >= score:
          last_score = score_stack.pop()
          last_ind = ind_stack.pop()
          ans = max(ans, min(y - last_ind, (last_score - score)) ** 2)
        
        score_stack.append(score)
        ind_stack.append(last_ind)
print(ans)


# Fixed version:
h, w = map(int, input().split())
mp = []
for _ in range(h):
  lst = list(map(int, input().split()))
  cum = []
  acc = 0
  for i in lst:
    if i == 0:
      acc += 1
    else:
      acc = 0
    cum.append(acc)
  mp.append(cum)
mp.append([-1] * w)

ans = 0
for x in range(w):
  score_stack = []
  ind_stack = []
  for y in range(h + 1):
#    print(score_stack, ind_stack)
    score = mp[y][x]
    if score_stack == []:
      score_stack.append(score)
      ind_stack.append(y)
    else:
      last_score = score_stack[-1]
      if last_score < score:
        score_stack.append(score)
        ind_stack.append(y)

      elif last_score == score:
        continue

      else:
        while score_stack != [] and score_stack[-1] >= score:
          last_score = score_stack.pop()
          last_ind = ind_stack.pop()
#          print(last_score, last_ind, ans)
          ans = max(ans, min(y - last_ind, last_score) ** 2)
        
        score_stack.append(score)
        ind_stack.append(last_ind)
print(ans)

# Buggy version:
H, W = map(int, input().split())
c = []
for i in range(H):
    c.append([int(i) for i in input().split()])
dp = [[0 for i in range(W)] for i in range(H)]
maxwidth = 0
for i in range(H):
    for j in range(W):
        dp[i][j] = (c[i][j] + 1) % 2
        maxwidth |= dp[i][j]

for i in range(1, H):
    for j in range(1, W):
        dp[i][j] = min(dp[i-1][j], dp[i-1][j-1], dp[i][j-1]) + 1
        maxwidth = max(maxwidth,dp[i][j])

print(maxwidth**2)


# Fixed version:
H, W = map(int, input().split())
c = []

for i in range(H):
    c.append([int(i) for i in input().split()])
dp = [[0 for i in range(W)] for i in range(H)]

maxwidth = 0

for i in range(H):
    for j in range(W):
        dp[i][j] = (c[i][j] + 1) % 2
        maxwidth |= dp[i][j]

for i in range(1, H):
    for j in range(1, W):
        if c[i][j]:
            continue
        else:
            dp[i][j] = min(dp[i-1][j], dp[i-1][j-1], dp[i][j-1]) + 1
            maxwidth = max(maxwidth, dp[i][j])

print(maxwidth**2)