Buggy python submission (verdict: Time Limit Exceeded):
import time
from collections import deque
H, W = map(int, input().split())
maze = [input()for _ in range(H)]


def bfs(queue: deque, reached: set) -> int:
    ans = 0
    dxdy = [[1, 0], [-1, 0], [0, 1], [0, -1]]
    while queue:
        d = queue.pop()
        if ans < d[2]:
            ans = d[2]
        for a in dxdy:
            x = d[0] + a[0]
            y = d[1] + a[1]
            if 0 <= x < W and 0 <= y < H and not reached[y][x]:
                queue.appendleft((x, y, d[2] + 1))
                reached[y][x] = True
    return ans


queue = deque()
reached = [[False for i in range(W)] for j in range(H)]
for i in range(H):
    for j in range(W):
        if maze[i][j] == '#':
            queue.append((j, i, 0))
            reached[i][j] = True
print(bfs(queue, reached))


Fixed submission:
from collections import deque
H, W = map(int, input().split())
maze = [input()for _ in range(H)]


def bfs(queue: deque, reached: set) -> int:
    ans = 0
    dxdy = [[1, 0], [-1, 0], [0, 1], [0, -1]]
    while queue:
        d = queue.pop()
        if ans < d[2]:
            ans = d[2]
        for a in dxdy:
            x = d[0] + a[0]
            y = d[1] + a[1]
            if 0 <= x < W and 0 <= y < H and not reached[y][x]:
                queue.appendleft((x, y, d[2] + 1))
                reached[y][x] = True
    return ans


queue = deque()
reached = [[False for i in range(W)] for j in range(H)]
for i in range(H):
    for j in range(W):
        if maze[i][j] == '#':
            queue.append((j, i, 0))
            reached[i][j] = True
print(bfs(queue, reached))

Buggy python submission (verdict: Time Limit Exceeded):
from collections import deque
H, W = map(int, input().split())
maze = [input()for _ in range(H)]


def bfs(queue: deque, reached: set) -> int:
    ans = 0
    dxdy = [[1, 0], [-1, 0], [0, 1], [0, -1]]
    while queue:
        d = queue.pop()
        if ans < d[2]:
            ans = d[2]
        for a in dxdy:
            x = d[0] + a[0]
            y = d[1] + a[1]
            if (x, y) not in reached and 0 <= x < W and 0 <= y < H:
                queue.appendleft((x, y, d[2] + 1))
                reached.add((x, y))
    return ans


queue = deque()
reached = set()
for i in range(H):
    for j in range(W):
        if maze[i][j] == '#':
            queue.append((j, i, 0))
            reached.add((j, i))
print(bfs(queue, reached))

Fixed submission:
from collections import deque
H, W = map(int, input().split())
maze = [input()for _ in range(H)]


def bfs(queue: deque, reached: set) -> int:
    ans = 0
    dxdy = [[1, 0], [-1, 0], [0, 1], [0, -1]]
    while queue:
        d = queue.pop()
        if ans < d[2]:
            ans = d[2]
        for a in dxdy:
            x = d[0] + a[0]
            y = d[1] + a[1]
            if 0 <= x < W and 0 <= y < H and not reached[y][x]:
                queue.appendleft((x, y, d[2] + 1))
                reached[y][x] = True
    return ans


queue = deque()
reached = [[False for i in range(W)] for j in range(H)]
for i in range(H):
    for j in range(W):
        if maze[i][j] == '#':
            queue.append((j, i, 0))
            reached[i][j] = True
print(bfs(queue, reached))