Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3
import sys
import numpy as np


def solve(H: int, W: int, A: "List[str]"):
    dist = np.full((H, W), np.inf)
    for h in range(H):
        for w in range(W):           
            if A[h][w] == '#':
                dist[h][w] = 0

    for h in range(H-1):
        dist[h+1, :] = np.minimum(dist[h, :] + 1, dist[h+1, :])
    for w in range(W-1):
        dist[:, w+1] = np.minimum(dist[:, w] + 1, dist[:, w+1])
    for h in range(H-1, 0, -1):
        dist[h-1, :] = np.minimum(dist[h, :] + 1, dist[h-1, :])
    for w in range(W-1, 0, -1):
        dist[:, w-1] = np.minimum(dist[:, w] + 1, dist[:, w-1])

    print(int(np.max(dist)))
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(H):
        for w in range(W):
            hh = max(h-1, 0)
            ww = max(w-1, 0)            
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[hh][w], dist[h][ww]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            hh = min(h+1, H-1)
            ww = min(w+1, W-1)
            dist[h][w] = min(dist[h][w], dist[h][ww] + 1, dist[hh][w] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3
import sys
import queue

def solve(H: int, W: int, A: "List[str]"):
    Q = queue.Queue()
    marked = [[False for w in range(W)] for h in range(H)]
    qlen = 0
    for h, line in enumerate(A):
        for w, c in enumerate(line):
            if c == '#':
                Q.put((h, w))
                qlen += 1
                marked[h][w] = True
    
    count = 0
    while not Q.empty():
        flag = False
        for _ in range(qlen):
            h, w = Q.get()
            qlen -= 1
            for hh, ww in [(h-1, w), (h+1, w), (h, w-1), (h, w+1)]:
                if hh < 0 or hh >= H or ww < 0 or ww >= W:
                    continue
                if marked[hh][ww]:
                    continue
                flag = True
                Q.put((hh, ww))
                qlen += 1
                marked[hh][ww] = True
        if flag:
            count += 1
    print(count)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3
import sys
import queue

def solve(H: int, W: int, A: "List[str]"):
    Q = queue.Queue()
    marked = [[False for w in range(W)] for h in range(H)]
    qlen = 0
    for h, line in enumerate(A):
        for w, c in enumerate(line):
            if c == '#':
                Q.put((h, w))
                qlen += 1
                marked[h][w] = True
    
    count = 0
    while not Q.empty():
        flag = False
        for _ in range(qlen):
            h, w = Q.get()
            qlen -= 1
            for hh, ww in [(h-1, w), (h+1, w), (h, w-1), (h, w+1)]:
                if hh < 0 or hh >= H or ww < 0 or ww >= W:
                    continue
                if marked[hh][ww]:
                    continue
                flag = True
                Q.put((hh, ww))
                qlen += 1
                marked[hh][ww] = True
        if flag:
            count += 1
    print(count)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3
import sys
import queue

def solve(H: int, W: int, black):
    Q = queue.Queue()
    marked = [[False] * W for h in range(H)]
    qlen = 0
    for h, w in black:
        Q.put((h, w))
        qlen += 1
        marked[h][w] = True
    
    count = 0
    while not Q.empty():
        flag = False
        for _ in range(qlen):
            h, w = Q.get()
            qlen -= 1
            for hh, ww in [(h-1, w), (h+1, w), (h, w-1), (h, w+1)]:
                if 0 <= hh <= H-1 and 0 <= ww <= W-1 and not marked[hh][ww]:
                    flag = True
                    Q.put((hh, ww))
                    qlen += 1
                    marked[hh][ww] = True
        if flag:
            count += 1
    print(count)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    black = []
    for h in range(H):
        line = next(tokens)
        for w, c in enumerate(line):
            if c == '#':
                black.append((h, w))
    solve(H, W, black)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3
import sys
import queue

def solve(H: int, W: int, black):
    Q = queue.Queue()
    marked = [[0] * W for h in range(H)]
    qlen = 0
    for h, w in black:
        Q.put((h, w))
        qlen += 1
        marked[h][w] = 1
    
    count = 0
    while not Q.empty():
        flag = False
        for _ in range(qlen):
            h, w = Q.get()
            qlen -= 1
            for hh, ww in [(h-1, w), (h+1, w), (h, w-1), (h, w+1)]:
                if not marked[hh][ww] and 0 <= hh <= H-1 and 0 <= ww <= W-1:
                    flag = True
                    Q.put((hh, ww))
                    qlen += 1
                    marked[hh][ww] = 1
        if flag:
            count += 1
    print(count)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    black = []
    for h in range(H):
        line = next(tokens)
        for w, c in enumerate(line):
            if c == '#':
                black.append((h, w))
    solve(H, W, black)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3
import sys
import queue

def solve(H: int, W: int, black):
    Q = queue.Queue()
    marked = [[0] * W for h in range(H)]
    qlen = 0
    for h, w in black:
        Q.put((h, w))
        qlen += 1
        marked[h][w] = 1
    
    count = 0
    while not Q.empty():
        flag = False
        for _ in range(qlen):
            h, w = Q.get()
            qlen -= 1
            for hh, ww in [(h-1, w), (h+1, w), (h, w-1), (h, w+1)]:
                if 0 <= hh <= H-1 and 0 <= ww <= W-1 and marked[hh][ww] == 0:
                    flag = True
                    Q.put((hh, ww))
                    qlen += 1
                    marked[hh][ww] = 1
        if flag:
            count += 1
    print(count)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    black = []
    for h in range(H):
        line = next(tokens)
        for w, c in enumerate(line):
            if c == '#':
                black.append((h, w))
    solve(H, W, black)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(W) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(W) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            else:
                dist[h][w] = dist[h][w]
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(W) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3
import sys
import heapq

def solve(H: int, W: int, black):
    Q = []
    marked = [[0] * W for h in range(H)]
    for h, w in black:
        heapq.heappush(Q, (0, h, w))
        marked[h][w] = 1
    dmax = 0
    while len(Q) > 0:
        d, h, w = heapq.heappop(Q)
        dmax = max(d, dmax)
        for hh, ww in [(h-1, w), (h+1, w), (h, w-1), (h, w+1)]:
            if 0 <= hh <= H-1 and 0 <= ww <= W-1 and marked[hh][ww] == 0:
                heapq.heappush(Q, (d+1, hh, ww))
                marked[hh][ww] = 1
    print(dmax)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    black = []
    for h in range(H):
        line = next(tokens)
        for w, c in enumerate(line):
            if c == '#':
                black.append((h, w))
    solve(H, W, black)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3
import sys
import bisect
import heapq

def solve(H: int, W: int, black):
    Q = []
    marked = [[0] * W for h in range(H)]
    for h, w in black:
        heapq.heappush(Q, (0, h, w))
        marked[h][w] = 1
    dmax = 0
    while len(Q) > 0:
        d, h, w = heapq.heappop(Q)
        dmax = max(d, dmax)
        for hh, ww in [(h-1, w), (h+1, w), (h, w-1), (h, w+1)]:
            if 0 <= hh <= H-1 and 0 <= ww <= W-1 and marked[hh][ww] == 0:
                heapq.heappush(Q, (d+1, hh, ww))
                marked[hh][ww] = 1
    print(dmax)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    black = []
    for h in range(H):
        line = next(tokens)
        for w, c in enumerate(line):
            if c == '#':
                black.append((h, w))
    solve(H, W, black)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3
import sys
import bisect
import heapq

def solve(H: int, W: int, A: "List[str]"):
    Q = []
    marked = [[0] * W for h in range(H)]
    for h in range(H):
        for w in range(W):
            if A[h][w] == '#':
                heapq.heappush(Q, (0, h, w))
                marked[h][w] = 1
    dmax = 0
    while len(Q) > 0:
        d, h, w = heapq.heappop(Q)
        dmax = max(d, dmax)
        for hh, ww in [(h-1, w), (h+1, w), (h, w-1), (h, w+1)]:
            if 0 <= hh <= H-1 and 0 <= ww <= W-1 and marked[hh][ww] == 0:
                heapq.heappush(Q, (d+1, hh, ww))
                marked[hh][ww] = 1
    print(dmax)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(W) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python3
import sys
import bisect
import heapq

def solve(H: int, W: int, A: "List[str]"):
    Q = []
    marked = [[0] * W for h in range(H)]
    for h in range(H):
        for w in range(W):
            if A[h][w] == '#':
                heapq.heappush(Q, (0, h, w))
                marked[h][w] = 1
    dmax = 0
    while len(Q) > 0:
        d, h, w = heapq.heappop(Q)
        dmax = max(d, dmax)
        if h-1 >= 0 and marked[h-1][w] == 0:
            heapq.heappush(Q, (d+1, h-1, w))
            marked[h-1][w] = 1
        if w-1 >= 0 and marked[h][w-1] == 0:
            heapq.heappush(Q, (d+1, h, w-1))
            marked[h][w-1] = 1
        if h+1 <= H-1 and marked[h+1][w] == 0:
            marked[h+1][w] = 1
            heapq.heappush(Q, (d+1, h+1, w))
        if w+1 <= W-1 and marked[h][w+1] == 0:
            marked[h][w+1] = 1
            heapq.heappush(Q, (d+1, h, w+1))
    print(dmax)
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(W) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys

inf = float('inf')

def solve(H: int, W: int, A: "List[str]"):
    dist = [[inf] * W for h in range(H)]
    for h in range(1, H):
        for w in range(1, W):
            if A[h][w] == '#':
                dist[h][w] = 0
            else:
                dist[h][w] = min(dist[h-1][w], dist[h][w-1]) + 1
    
    dmax = 0
    for h in range(H-1, -1, -1):
        for w in range(W-1, -1, -1):
            if A[h][w] == '#':
                dist[h][w] = 0
            elif h+1 <= H-1 and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], min(dist[h+1][w], dist[h][w+1]) + 1)
            elif w+1 == W and h+1 <= H-1:
                dist[h][w] = min(dist[h][w], dist[h+1][w] + 1)
            elif h+1 == H and w+1 <= W-1:
                dist[h][w] = min(dist[h][w], dist[h][w+1] + 1)
            dmax = max(dist[h][w], dmax)
    print(dmax) 
    return


# Generated by 1.1.4 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    H = int(next(tokens))  # type: int
    W = int(next(tokens))  # type: int
    A = [ next(tokens) for _ in range(H) ]  # type: "List[str]"
    solve(H, W, A)

if __name__ == '__main__':
    main()