# coding: utf-8

# Your code here!

import collections



h,w = [int(i) for i in input().split()]

board = [eval(input()) for j in range(h)] # 縦「n」行



d4 = [[1,0],[0,1],[-1,0],[0,-1]]

memo = [[-1]*w for j in range(h)]

dist = [[100000]*w for j in range(h)]





q = collections.deque()

for i in range(h):

    for j in range(w):

        if board[i][j] == "#":

            memo[i][j] = 1

            q.append((i,j,0))



while len(q) != 0:

#    print(memo)

    i,j,c = q.popleft()

    dist[i][j] = c

    for k in d4:

#        print(k)

        ii,jj = k

        if  i+ii < 0 or i+ii>=h or j+jj <0 or j+jj>=w:

#            print("out",i+ii,j+jj)

            continue

        if memo[i+ii][j+jj] < 0:

#            print("put")

            q.append((i+ii,j+jj,c+1))

            memo[i+ii][j+jj] = 1



ans = 0      

for i in range(h):

    for j in range(w):

        ans = max(ans,dist[i][j])



print(ans)

#print(dist)









                

            

        
import collections #deque



h,w = [int(i) for i in input().split()]

board = [eval(input()) for j in range(h)] # 縦「n」行



dx4=[0, 1, 0,-1]

dy4=[1, 0,-1, 0]

#dx8=[0, 1, 0,-1,1,-1,1,-1]

#dy8=[1, 0,-1, 0,1,1,-1,-1]



#memo: 負なら未確認、0以上なら最短距離

memo = [[-1]*w for _ in range(h)]



q = collections.deque()

#初期状態をキューに入れる-----------------------------------------------------

#キューに入れる時点で使用したかどうかのmemoを更新-----------------------------

for i in range(h):

    for j in range(w):

        if board[i][j] == "#":

            q.append((i,j)) #初期状態をキューに入れる

            memo[i][j] = 0 #初期状態を訪問済みにする



while len(q) != 0:

    x,y = q.popleft() #キューから情報を取り出す

    #foreach (x,y)のお隣さん に対して処理-------------------------------------

    for i in range(4):

        nx = x + dx4[i]

        ny = y + dy4[i]

        #範囲外ならスキップ---------------------------------------------------

        if nx < 0 or nx>=h or ny <0 or ny>=w: continue

        #壁ならスキップ-------------------------------------------------------

        #if board[nx][ny] == "#": continue

        #(nx,ny)が確認済みならスキップ----------------------------------------

        if memo[nx][ny] >= 0: continue

        #(nx,ny)が未確認のとき、確認済みにしてキューに入れる------------------

        memo[nx][ny] = memo[x][y]+1

        q.append((nx,ny))

        #経路復元が必要なとき-------------------------------------------------

        # prev[nx][ny] = [x,y]



ans = 0      

for i in range(h):

    for j in range(w):

        ans = max(ans,memo[i][j])



print(ans)

# coding: utf-8
# Your code here!
import collections

h, w = [int(i) for i in input().split()]
board = [eval(input()) for j in range(h)]  # 縦「n」行
d4 = [[1, 0], [0, 1], [-1, 0], [0, -1]]
memo = [[-1] * w for j in range(h)]
dist = [[100000] * w for j in range(h)]
q = collections.deque()
for i in range(h):
    for j in range(w):
        if board[i][j] == "#":
            memo[i][j] = 1
            q.append((i, j, 0))
while len(q) != 0:
    #    print(memo)
    i, j, c = q.popleft()
    dist[i][j] = c
    for k in d4:
        #        print(k)
        ii, jj = k
        if i + ii < 0 or i + ii >= h or j + jj < 0 or j + jj >= w:
            #            print("out",i+ii,j+jj)
            continue
        if memo[i + ii][j + jj] < 0:
            #            print("put")
            q.append((i + ii, j + jj, c + 1))
            memo[i + ii][j + jj] = 1
ans = 0
for i in range(h):
    for j in range(w):
        ans = max(ans, dist[i][j])
print(ans)
# print(dist)

import collections  # deque

h, w = [int(i) for i in input().split()]
board = [eval(input()) for j in range(h)]  # 縦「n」行
dx4 = [0, 1, 0, -1]
dy4 = [1, 0, -1, 0]
# dx8=[0, 1, 0,-1,1,-1,1,-1]
# dy8=[1, 0,-1, 0,1,1,-1,-1]
# memo: 負なら未確認、0以上なら最短距離
memo = [[-1] * w for _ in range(h)]
q = collections.deque()
# 初期状態をキューに入れる-----------------------------------------------------
# キューに入れる時点で使用したかどうかのmemoを更新-----------------------------
for i in range(h):
    for j in range(w):
        if board[i][j] == "#":
            q.append((i, j))  # 初期状態をキューに入れる
            memo[i][j] = 0  # 初期状態を訪問済みにする
while len(q) != 0:
    x, y = q.popleft()  # キューから情報を取り出す
    # foreach (x,y)のお隣さん に対して処理-------------------------------------
    for i in range(4):
        nx = x + dx4[i]
        ny = y + dy4[i]
        # 範囲外ならスキップ---------------------------------------------------
        if nx < 0 or nx >= h or ny < 0 or ny >= w:
            continue
        # 壁ならスキップ-------------------------------------------------------
        # if board[nx][ny] == "#": continue
        # (nx,ny)が確認済みならスキップ----------------------------------------
        if memo[nx][ny] >= 0:
            continue
        # (nx,ny)が未確認のとき、確認済みにしてキューに入れる------------------
        memo[nx][ny] = memo[x][y] + 1
        q.append((nx, ny))
        # 経路復元が必要なとき-------------------------------------------------
        # prev[nx][ny] = [x,y]
ans = 0
for i in range(h):
    for j in range(w):
        ans = max(ans, memo[i][j])
print(ans)

-# coding: utf-8 -# Your code here! -import collections +import collections  # deque -d4 = [[1, 0], [0, 1], [-1, 0], [0, -1]] -memo = [[-1] * w for j in range(h)] -dist = [[100000] * w for j in range(h)] +dx4 = [0, 1, 0, -1] +dy4 = [1, 0, -1, 0] +# dx8=[0, 1, 0,-1,1,-1,1,-1] +# dy8=[1, 0,-1, 0,1,1,-1,-1] +# memo: 負なら未確認、0以上なら最短距離 +memo = [[-1] * w for _ in range(h)] -            memo[i][j] = 1 -            q.append((i, j, 0)) +            q.append((i, j))  # 初期状態をキューに入れる +            memo[i][j] = 0  # 初期状態を訪問済みにする -    #    print(memo) -    i, j, c = q.popleft() -    dist[i][j] = c -    for k in d4: -        #        print(k) -        ii, jj = k -        if i + ii < 0 or i + ii >= h or j + jj < 0 or j + jj >= w: -            #            print("out",i+ii,j+jj) +    x, y = q.popleft()  # キューから情報を取り出す +    for i in range(4): +        nx = x + dx4[i] +        ny = y + dy4[i] +        if nx < 0 or nx >= h or ny < 0 or ny >= w: -        if memo[i + ii][j + jj] < 0: -            #            print("put") -            q.append((i + ii, j + jj, c + 1)) -            memo[i + ii][j + jj] = 1 +        # if board[nx][ny] == "#": continue +        if memo[nx][ny] >= 0: +            continue +        memo[nx][ny] = memo[x][y] + 1 +        q.append((nx, ny)) +        # prev[nx][ny] = [x,y] -        ans = max(ans, dist[i][j]) +        ans = max(ans, memo[i][j]) -# print(dist)