import sys

sys.setrecursionlimit(10**6)

input = sys.stdin.readline



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

INF = 10**18

q = []



visited = [[True]*(W+2)]

visited += [[True] + [x == '#' for x in input().rstrip()] + [True] for _ in range(H)]

visited.append([True]*(W+2))

  

for i in range(1,H+1):

  for j in range(1,W+1):

    if visited[i][j]:

      q.append((i,j))



moves = [(0,1),(0,-1),(1,0),(-1,0)]



ans = -1

while q:

  qq = []

  ans += 1

  for x,y in q:

    if not visited[x-1][y]:

      visited[x-1][y] = True

      qq.append((x-1,y))

    if not visited[x+1][y]:

      visited[x+1][y] = True

      qq.append((x+1,y))

    if not visited[x][y-1]:

      visited[x][y-1] = True

      qq.append((x,y-1))

    if not visited[x][y+1]:

      visited[x][y+1] = True

      qq.append((x,y+1))

  q = qq

  

print(ans)
import numpy as np

import sys

# 距離K以内にxが居ない

# xからの距離を測る



buf = sys.stdin.buffer

R,C = list(map(int,buf.readline().split()))

black = np.zeros((R+2,C+2),dtype=np.bool)

black[1:-1,1:] = (np.frombuffer(buf.read(R*(C+1)),dtype='S1') == b'#').reshape(R,C+1)



INF = 10 ** 9

dist = np.zeros((R,C),dtype=np.int32)

dist[~black[1:-1,1:-1]] = INF



for n in range(1,R):

  np.minimum(dist[n-1]+1,dist[n],out=dist[n])

for n in range(R-2,-1,-1):

  np.minimum(dist[n+1]+1,dist[n],out=dist[n])



for n in range(1,C):

  np.minimum(dist[:,n-1]+1,dist[:,n],out=dist[:,n])

for n in range(C-2,-1,-1):

  np.minimum(dist[:,n+1]+1,dist[:,n],out=dist[:,n])



answer = dist.max()

print(answer)

import sys

sys.setrecursionlimit(10**6)
input = sys.stdin.readline
H, W = list(map(int, input().split()))
INF = 10**18
q = []
visited = [[True] * (W + 2)]
visited += [[True] + [x == "#" for x in input().rstrip()] + [True] for _ in range(H)]
visited.append([True] * (W + 2))
for i in range(1, H + 1):
    for j in range(1, W + 1):
        if visited[i][j]:
            q.append((i, j))
moves = [(0, 1), (0, -1), (1, 0), (-1, 0)]
ans = -1
while q:
    qq = []
    ans += 1
    for x, y in q:
        if not visited[x - 1][y]:
            visited[x - 1][y] = True
            qq.append((x - 1, y))
        if not visited[x + 1][y]:
            visited[x + 1][y] = True
            qq.append((x + 1, y))
        if not visited[x][y - 1]:
            visited[x][y - 1] = True
            qq.append((x, y - 1))
        if not visited[x][y + 1]:
            visited[x][y + 1] = True
            qq.append((x, y + 1))
    q = qq
print(ans)

import numpy as np
import sys

# 距離K以内にxが居ない
# xからの距離を測る
buf = sys.stdin.buffer
R, C = list(map(int, buf.readline().split()))
black = np.zeros((R + 2, C + 2), dtype=np.bool)
black[1:-1, 1:] = (np.frombuffer(buf.read(R * (C + 1)), dtype="S1") == b"#").reshape(
    R, C + 1
)
INF = 10**9
dist = np.zeros((R, C), dtype=np.int32)
dist[~black[1:-1, 1:-1]] = INF
for n in range(1, R):
    np.minimum(dist[n - 1] + 1, dist[n], out=dist[n])
for n in range(R - 2, -1, -1):
    np.minimum(dist[n + 1] + 1, dist[n], out=dist[n])
for n in range(1, C):
    np.minimum(dist[:, n - 1] + 1, dist[:, n], out=dist[:, n])
for n in range(C - 2, -1, -1):
    np.minimum(dist[:, n + 1] + 1, dist[:, n], out=dist[:, n])
answer = dist.max()
print(answer)

+import numpy as np -sys.setrecursionlimit(10**6) -input = sys.stdin.readline -H, W = list(map(int, input().split())) -INF = 10**18 -q = [] -visited = [[True] * (W + 2)] -visited += [[True] + [x == "#" for x in input().rstrip()] + [True] for _ in range(H)] -visited.append([True] * (W + 2)) -for i in range(1, H + 1): -    for j in range(1, W + 1): -        if visited[i][j]: -            q.append((i, j)) -moves = [(0, 1), (0, -1), (1, 0), (-1, 0)] -ans = -1 -while q: -    qq = [] -    ans += 1 -    for x, y in q: -        if not visited[x - 1][y]: -            visited[x - 1][y] = True -            qq.append((x - 1, y)) -        if not visited[x + 1][y]: -            visited[x + 1][y] = True -            qq.append((x + 1, y)) -        if not visited[x][y - 1]: -            visited[x][y - 1] = True -            qq.append((x, y - 1)) -        if not visited[x][y + 1]: -            visited[x][y + 1] = True -            qq.append((x, y + 1)) -    q = qq -print(ans) +# 距離K以内にxが居ない +# xからの距離を測る +buf = sys.stdin.buffer +R, C = list(map(int, buf.readline().split())) +black = np.zeros((R + 2, C + 2), dtype=np.bool) +black[1:-1, 1:] = (np.frombuffer(buf.read(R * (C + 1)), dtype="S1") == b"#").reshape( +    R, C + 1 +) +INF = 10**9 +dist = np.zeros((R, C), dtype=np.int32) +dist[~black[1:-1, 1:-1]] = INF +for n in range(1, R): +    np.minimum(dist[n - 1] + 1, dist[n], out=dist[n]) +for n in range(R - 2, -1, -1): +    np.minimum(dist[n + 1] + 1, dist[n], out=dist[n]) +for n in range(1, C): +    np.minimum(dist[:, n - 1] + 1, dist[:, n], out=dist[:, n]) +for n in range(C - 2, -1, -1): +    np.minimum(dist[:, n + 1] + 1, dist[:, n], out=dist[:, n]) +answer = dist.max() +print(answer)