You are given a grid of squares with H horizontal rows and W vertical columns, where each square is painted white or black. Characters from A11 to AHW represent the colors of the squares. Aij is "#" if the square at the i-th row from the top and the j-th column from the left is black, and Aij is "." if that square is white. We will repeatedly perform the following operation until all the squares are black: Every white square that shares a side with a black square becomes black. Find the number of operations that will be performed. The initial grid has at least one black square.

Constraints:
1 ≤ H, W ≤ 1000
Aij is "#" or "."
The given grid has at least one black square.

Input:
Input is given from Standard Input in the following format:
H W
A11A12...A1W
:
AH1AH2...AHW

Output:
Print the number of operations that will be performed.

Sample Input 1:
3 3
...
.#.
...

Sample Output 1:
2
After one operation, all but the corners of the grid will be black. After one more operation, all the squares will be black.

Sample Input 2:
6 6
..#..#
......
#..#..
......
.#....
....#.

Sample Output 2:
3

# Buggy version:
import numpy as np

h , w = map(int, input().split())
visited = np.zeros((h,w))

for y in range(h):
    _in = input()
    for x, value in enumerate(_in):
        if value == '.':
            visited[y][x] = 10**9
for i in range(1,h):
    visited[i,:] = np.minimum(visited[i,:],visited[i-1,:]+1)
for i in reversed(range(h-1)):
    visited[i,:] = np.minimum(visited[i,:],visited[i+1,:]+1)
for j in range(1,h):
    visited[:,j] = np.minimum(visited[:,j],visited[:,j-1]+1)
for j in reversed(range(h-1)):
    visited[:,j] = np.minimum(visited[:,j],visited[:,j+1]+1)
print(np.max(visited))

# Fixed version:
import numpy as np

h , w = map(int, input().split())
visited = np.zeros((h,w),dtype=int)

for y in range(h):
    _in = input()
    for x, value in enumerate(_in):
        if value == '.':
            visited[y][x] = 10**9
            
for i in range(1,h):
    visited[i,:] = np.minimum(visited[i,:],visited[i-1,:]+1)
for i in reversed(range(h-1)):
    visited[i,:] = np.minimum(visited[i,:],visited[i+1,:]+1)
for j in range(1,w):
    visited[:,j] = np.minimum(visited[:,j],visited[:,j-1]+1)
for j in reversed(range(w-1)):
    visited[:,j] = np.minimum(visited[:,j],visited[:,j+1]+1)
print(np.max(visited))

# Buggy version:
import numpy as np

H,W = map(int,input().split())
use = np.zeros((H,W),dtype=int)
for i in range(H):
    s = input()
    for j,st in enumerate(s):
        if st == ".":
            use[i][j] = 10**9
        else:

for i in range(1,H):
    use[i,:] = np.minimum(use[i,:],use[i-1,:]+1)
for i in reversed(range(H-1)):
    use[i,:] = np.minimum(use[i,:],use[i+1,:]+1)
for j in range(1,W):
    use[:,j] = np.minimum(use[:,j],use[:,j-1]+1)
for j in reversed(range(W-1)):
    use[:,j] = np.minimum(use[:,j],use[:,j+1]+1)

print(np.max(use))

# Fixed version:
import numpy as np

H,W = map(int,input().split())
use = np.zeros((H,W),dtype=int)
for i in range(H):
    s = input()
    for j,st in enumerate(s):
        if st == ".":
            use[i][j] = 10**10
        else:
            use[i][j] = 0

for i in range(1,H):
    use[i,:] = np.minimum(use[i,:],use[i-1,:]+1)
for i in reversed(range(H-1)):
    use[i,:] = np.minimum(use[i,:],use[i+1,:]+1)
for j in range(1,W):
    use[:,j] = np.minimum(use[:,j],use[:,j-1]+1)
for j in reversed(range(W-1)):
    use[:,j] = np.minimum(use[:,j],use[:,j+1]+1)

print(np.max(use))

# Buggy version:
from collections import deque
H ,W = map(int, input().split())#↓H行数 →W列数
List = [list(str(input())) for i in range(H)]
#H=3
#W=3
#List=[['.', '.', '.'], ['.', '#', '.'], ['.', '.', '.']]
cheak=[['0' for i in range(W)] for j in range(H)]

q = deque([])

for h in range(H):
    for w in range(W):
        if List[h][w]=='#':
            cheak[h][w]='1'
            q.append([h,w])
#print(List)
#print(cheak)
move=[[1,0],[-1,0],[0,1],[0,-1]]
num=-1
#print(q)
while q:
    for rt in range(len(q)):
        i=q.popleft()
        for u in move:
            if 0<=i[0]+u[0]<=H-1 and 0<=i[1]+u[1]<=W-1 and cheak[i[0]+u[0]][i[1]+u[1]]=='0':
                q.append([i[0]+u[0],i[1]+u[1]])
                cheak[i[0]+u[0]][i[1]+u[1]]='1'
    #print(cheak)
    num+=1
print(num)        


# Fixed version:
from collections import deque
import sys
input = sys.stdin.readline

H ,W = map(int, input().split())#↓H行数 →W列数
List = [list(str(input())) for i in range(H)]
#H=3
#W=3
#List=[['.', '.', '.'], ['.', '#', '.'], ['.', '.', '.']]
cheak=[['0' for i in range(W)] for j in range(H)]

q = deque([])

for h in range(H):
    for w in range(W):
        if List[h][w]=='#':
            cheak[h][w]='1'
            q.append([h,w])
#print(List)
#print(cheak)
move=[[1,0],[-1,0],[0,1],[0,-1]]
num=-1
#print(q)
while q:
    for rt in range(len(q)):
        i=q.popleft()
        for u in move:
            if 0<=i[0]+u[0]<=H-1 and 0<=i[1]+u[1]<=W-1 and cheak[i[0]+u[0]][i[1]+u[1]]=='0':
                q.append([i[0]+u[0],i[1]+u[1]])
                cheak[i[0]+u[0]][i[1]+u[1]]='1'
    #print(cheak)
    num+=1
print(num)

# Buggy version:
h, w = map(int, input().split())
a = [['*' for _ in range(w+2)]]
for _ in range(h):
    a.append(['*'] + list(input()) + ['*'])
a.append(['*' for _ in range(w+2)])

q = set()

def encode(i, j):
    return (i+1)*w + j

def decode(x):
    i = x // w - 1
    j = x % w
    return [i, j]

for i in range(1, h+1):
    for j in range(1, w+1):
        if a[i][j] == '#':
            q.add(encode(i, j))

for ans in range(h+w):
    nq = set()
    for x in q:
        i, j = decode(x)
        if a[i][j] == '#':
            for k in [-1,1]:
                if a[i+k][j] == '.':
                    nq.add(encode(i+k, j))
                    a[i+k][j] = '#'
            for k in [-1,1]:
                if a[i][j+k] == '.':
                    nq.add(encode(i, j+k))
                    a[i][j+k] = '#'
    if len(nq) == 0:
        print(ans)
        exit()
    else:
        q = set()
        q = q | nq


# Fixed version:
h, w = map(int, input().split())
a = [['*' for _ in range(w+2)]]
for _ in range(h):
    a.append(['*'] + list(input()) + ['*'])
a.append(['*' for _ in range(w+2)])

q = set()

def encode(i, j):
    return i*w + j-1

def decode(x):
    i = x // w
    j = x % w + 1
    return [i, j]

for i in range(1, h+1):
    for j in range(1, w+1):
        if a[i][j] == '#':
            q.add(encode(i, j))

for ans in range(h+w):
    nq = set()
    for x in q:
        i, j = decode(x)
        for k in [-1,1]:
            if a[i+k][j] == '.':
                nq.add(encode(i+k, j))
                a[i+k][j] = '#'
        for k in [-1,1]:
            if a[i][j+k] == '.':
                nq.add(encode(i, j+k))
                a[i][j+k] = '#'
    if len(nq) == 0:
        print(ans)
        exit()
    else:
        q = set()
        q = q | nq

# Buggy version:
from collections import deque

h, w = map(int, input().split())
a = [list(input()) for _ in range(h)]
print(a)
dist = [[-1]*w for _ in range(h)]  # 黒ならdist[i][j]は0、白なら-1

black_cells = deque()

for i in range(h):
    for j in range(w):
        if a[i][j] == '#':
            black_cells.append([i, j])
            dist[i][j] = 0

def bfs(black_cells, dist):
    d = 0
    while black_cells:
        print(dist)
        h_black, w_black = black_cells.popleft()
        d=dist[h_black][w_black]
        for dy, dx in ((1, 0), (0, 1), (-1, 0), (0, -1)):
            new_h = h_black+dy
            new_w = w_black+dx
            if new_h < 0 or h <= new_h or new_w < 0 or w <= new_w:
                continue
            if dist[new_h][new_w] == -1:
                dist[new_h][new_w] = d+1
                black_cells.append([new_h, new_w])
    return max(sum(dist,[]))

d = bfs(black_cells, dist)
print(d)


# Fixed version:
from collections import deque
import sys
input = sys.stdin.readline

h, w = map(int, input().split())
a = [list(input()) for _ in range(h)]
dist = [[-1]*w for _ in range(h)]  # 黒ならdist[i][j]は0、白なら-1

black_cells = deque()

for i in range(h):
    for j in range(w):
        if a[i][j] == '#':
            black_cells.append((i, j))
            dist[i][j] = 0

def bfs(black_cells, dist):
    d = 0
    while black_cells:
        h_black, w_black = black_cells.popleft()
        d=dist[h_black][w_black]
        for dy, dx in ((1, 0), (0, 1), (-1, 0), (0, -1)):
            new_h = h_black+dy
            new_w = w_black+dx
            if new_h < 0 or h <= new_h or new_w < 0 or w <= new_w:
                continue
            if dist[new_h][new_w] == -1:
                dist[new_h][new_w] = d+1
                black_cells.append((new_h, new_w))
    return d

d = bfs(black_cells, dist)
print(d)

# Buggy version:
from collections import deque

h, w = list(map(int, input().split()))
f = []
q = deque()
for i in range(h):
    l = input()
    for j, c in enumerate(l):
        if c == '#':
            q.append((0, i, j))
    f.append(l)

visited = [[False] * w for _ in [0] * h]
for d, i, j in q:
    visited[i][j] = True

ans = 0
move = [(0, 1), (0, -1), (1, 0), (-1, 0)]

while q:
    d, i, j = q.popleft()
    ans = d
    for di, dj in move:
        ni, nj = i + di, j + dj
        if ni < 0 or h <= ni or nj < 0 or w <= nj:
            continue
        if visited[ni][nj]:
            continue
        visited[i][j] = True
        q.append((d + 1, ni, nj))

print(ans)


# Fixed version:
from collections import deque

h, w = list(map(int, input().split()))
f = []
q = deque()
for i in range(h):
    l = input()
    for j, c in enumerate(l):
        if c == '#':
            q.append((0, i, j))
    f.append(l)

visited = [[False] * w for _ in [0] * h]
for d, i, j in q:
    visited[i][j] = True

ans = 0
move = [(0, 1), (0, -1), (1, 0), (-1, 0)]

while q:
    d, i, j = q.popleft()
    ans = d
    for di, dj in move:
        ni, nj = i + di, j + dj
        if ni < 0 or h <= ni or nj < 0 or w <= nj:
            continue
        if visited[ni][nj]:
            continue
        visited[ni][nj] = True
        q.append((d + 1, ni, nj))

print(ans)

# Buggy version:
from collections import deque

H, W = map(int, input().split())
grid = [input() for _ in range(H)]

dxdy = [(-1,0), (1,0), (0,-1), (0,1)]
INF = 999999
que = deque()

dist = [[INF] * W for _ in range(H)]
for i in range(H):
    for j in range(W):
        if grid[i][j] == "#":
            dist[i][j] = 0
            que.append((i,j))

ans = 0
while len(que) > 0:
    h, w = que.popleft()
    for dx, dy in dxdy:
        nx = w + dx
        ny = h + dy
        if ny<0 or ny>=H or nx<0 or nx>=W or dist[ny][nx] < INF:
            continue
        dist[ny][nx] = min(dist[ny][nx], dist[h][w]+1)
        ans = max(ans, dist[ny][nx])
        que.append((ny,nx))

print(ans)

# Fixed version:
from collections import deque

H, W = map(int, input().split())
grid = [input() for _ in range(H)]

dxdy = [(-1,0), (1,0), (0,-1), (0,1)]
INF = 999999
que = deque()

dist = [[INF] * W for _ in range(H)]
for i, row in enumerate(grid):
    for j, s in enumerate(row):
        if s == "#":
            dist[i][j] = 0
            que.append(i*W + j)

ans = 0
while len(que) > 0:
    num = que.popleft()
    h = num // W
    w = num % W
    for dx, dy in dxdy:
        nx = w + dx
        ny = h + dy
        if ny<0 or ny>=H or nx<0 or nx>=W:
            continue
        if dist[ny][nx] == INF:
            que.append(ny * W + nx)
        dist[ny][nx] = min(dist[ny][nx], dist[h][w]+1)
        ans = max(ans, dist[ny][nx])

print(ans)

# Buggy version:
import array
import itertools
from collections import defaultdict, deque


def log(s):
    # print("| " + str(s), file=sys.stderr)
    pass


def output(x):
    print(x, flush=True)


def input_ints():
    return map(int, input().split())


def solve():
    def fill(queue):
        footsteps = [[None] * width for _ in range(height)]
        for p, s in queue:
            footsteps[p[1]][p[0]] = -1

        while queue:
            p, s = queue.popleft()
            x, y = p
            footsteps[y][x] = s

            if x > 0 and footsteps[y][x - 1] is None:
                queue.append(((x - 1, y), s + 1))
                footsteps[y][x - 1] = -1
            if x < width - 1 and footsteps[y][x + 1] is None:
                queue.append(((x + 1, y), s + 1))
                footsteps[y][x + 1] = -1
            if y > 0 and footsteps[y - 1][x] is None:
                queue.append(((x, y - 1), s + 1))
                footsteps[y - 1][x] = -1
            if y < height - 1 and footsteps[y + 1][x] is None:
                queue.append(((x, y + 1), s + 1))
                footsteps[y + 1][x] = -1

        return s

    height, width = tuple(input_ints())
    # field = [input() for _ in range(height)]
    queue = deque()

    # for y, line in enumerate(field):
    #     for x, c in enumerate(line):
    #         if c == '#':
    #             queue.append(((x, y), 0))
    queue.append(((10, 10), 0))

    return fill(queue)


def main():
    print(solve())


main()


# Fixed version:
import array
import itertools
from collections import defaultdict, deque


def log(s):
    # print("| " + str(s), file=sys.stderr)
    pass


def output(x):
    print(x, flush=True)


def input_ints():
    return map(int, input().split())


def solve():
    def fill(queue):
        footsteps = [[None] * width for _ in range(height)]

        for x, y in queue:
            footsteps[y][x] = 0

        s = 0
        while queue:
            queue2 = deque()
            s += 1
            while queue:
                x, y = queue.popleft()

                if x > 0 and footsteps[y][x - 1] is None:
                    queue2.append((x - 1, y))
                    footsteps[y][x - 1] = s
                if x < width - 1 and footsteps[y][x + 1] is None:
                    queue2.append((x + 1, y))
                    footsteps[y][x + 1] = s
                if y > 0 and footsteps[y - 1][x] is None:
                    queue2.append((x, y - 1))
                    footsteps[y - 1][x] = s
                if y < height - 1 and footsteps[y + 1][x] is None:
                    queue2.append((x, y + 1))
                    footsteps[y + 1][x] = s

            queue = queue2

        return s - 1

    height, width = tuple(input_ints())
    field = [input() for _ in range(height)]
    queue = deque()

    for y, line in enumerate(field):
        for x, c in enumerate(line):
            if c == '#':
                queue.append((x, y))
    # queue.append((10, 10))


    return fill(queue)


def main():
    print(solve())


main()

# Buggy version:
from collections import deque

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

grid = [[-1]*W for _ in range(H)]]

queue = deque([])

ans = 0

# while True:
#     f = 0
for i in range(H):
    s = input()
    for j, ss in enumerate(s):
        if ss = ="#":
            queue.append((i, j))
            grid[i][j] = 0

#黒点をスタート地点とし、上下左右に移動した時の移動距離を記録していく
while queue:
    h, w = queue.popleft()
    for i in [h-1, h+1]:
            if i >= 0 and i < H:
                if grid[i][w] == -1:
                    grid[i][w] = grid[h][w]+1
    for j in [w-1, w+1]:
        if j >= 0 and j < W:
            if grid[h][j] == -1:
                grid[h][j] = grid[h][w]+1

print(max(max[(b) for b in grid]))


# Fixed version:
from collections import deque

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

grid = [[-1]*W for _ in range(H)]

queue = deque([])

ans = 0

# while True:
#     f = 0
for i in range(H):
    s = input()
    for j, ss in enumerate(s):
        if ss =="#":
            queue.append((i, j))
            grid[i][j] = 0

#黒点をスタート地点とし、上下左右に移動した時の移動距離を記録していく
while queue:
    h, w = queue.popleft()
    for i in [h-1, h+1]:
            if i >= 0 and i < H:
                if grid[i][w] == -1:
                    grid[i][w] = grid[h][w]+1
                    queue.append((i, w))
    for j in [w-1, w+1]:
        if j >= 0 and j < W:
            if grid[h][j] == -1:
                grid[h][j] = grid[h][w]+1
                queue.append((h, j))

# print(grid)
print(max([max(b) for b in grid]))

# Buggy version:
from collections import deque
import sys

input = sys.stdin.readline

H, W = map(int, input().split())
a = [input() for _ in range(H)]

dist = [[-1] * W for _ in range(H)]
dq = deque((r, c) for r in range(H) for c in range(W) if a[r][c] == '#')


def out_of_range(r, c):
    return not (0 <= r < H and 0 <= c < W)


dr_s = (0, 0, -1, 1)
dc_s = (-1, 1, 0, 0)

d = 0
while dq:
    r, c = dq.popleft()
    d = dist[r][c]
    for dr, dc in zip(dr_s, dc_s):
        nr = r + dr
        nc = c + dc
        if out_of_range(nr, nc): continue
        if dist[nr][nc] != -1: continue
        dist[nr][nc] = d + 1
        dq.append((nr, nc))

print(d)


# Fixed version:
import sys

input = sys.stdin.readline

from collections import deque

H, W = map(int, input().split())
a = [input() for _ in range(H)]

dist = [[-1] * W for _ in range(H)]
dq = deque()

for r in range(H):
    for c in range(W):
        if a[r][c] == '#':
            dist[r][c] = 0
            dq.append((r, c))


def in_range(r, c):
    return 0 <= r < H and 0 <= c < W


dr_s = (0, 0, -1, 1)
dc_s = (-1, 1, 0, 0)

d = 0
while dq:
    r, c = dq.popleft()
    d = dist[r][c]
    for dr, dc in zip(dr_s, dc_s):
        nr = r + dr
        nc = c + dc
        if not in_range(nr, nc): continue
        if dist[nr][nc] != -1: continue
        dist[nr][nc] = d + 1
        dq.append((nr, nc))

print(d)

# Buggy version:
from collections import deque

h,w = map(int,input().split())
matrix = [[1]*(w+2)] + [list("a" + input() + "a") for _ in range(h)] + [[1]*(w+2)]

matrix_list1 = deque()
cnt = -1

for i in range(1,h+1):
    for j in range(1,w+1):
        if matrix[i][j] == "#":
            matrix[i][j] = 1
            matrix_list1.append([i,j])
        else:
            matrix[i][j] = 0

while len(matrix_list1) != 0:     
    for _ in range(len(matrix_list1)):
        x,y = matrix_list1.popleft()
        if not matrix[x+1][y]:
            matrix[x+1][y] = 1
            matrix_list1.append([x+1,y])
        if not matrix[x-1][y]:
            matrix[x-1][y] = 1
            matrix_list1.append([x-1,y])
        if not matrix[x][y+1]:
            matrix[x][y+1] = 1
            matrix_list1.append([x,y+1])
        if not matrix[x][y-1]:
            matrix[x][y-1] = 1
            matrix_list1.append([x,y-1])
    cnt += 1
    
print(cnt)

# Fixed version:
from collections import deque

h,w = map(int,input().split())
matrix = [["a" for _ in range(w+2)]] + [list("a" + input() + "a") for _ in range(h)] + [["a" for _ in range(w+2)]]

matrix_list1 = deque()
cnt = 0

for i in range(1,h+1):
    for j in range(1,w+1):
        if matrix[i][j] == "#":
            matrix_list1.append([i,j])

while len(matrix_list1) != 0:     
    for _ in range(len(matrix_list1)):
        x,y = matrix_list1.popleft()
        if matrix[x+1][y] == ".":
            matrix[x+1][y] = "#"
            matrix_list1.append([x+1,y])
        if matrix[x-1][y] == ".":
            matrix[x-1][y] = "#"
            matrix_list1.append([x-1,y])
        if matrix[x][y+1] == ".":
            matrix[x][y+1] = "#"
            matrix_list1.append([x,y+1])
        if matrix[x][y-1] == ".":
            matrix[x][y-1] = "#"
            matrix_list1.append([x,y-1])
    else:
        if len(matrix_list1) > 0:
            cnt += 1
    
print(cnt)

# Buggy version:
import sys
from collections import deque
input = sys.stdin.readline

m = [list(map(lambda x: 1 if x=="#" else 0, input())) for _ in range(H)]
black = [(i, j, 0) for i in range(H) for j in range(W) if m[i][j] == 1]

# print(m)
# print(black)

queue = deque(black)
queue_append = queue.append
ans = 0
while queue:
    p = queue.popleft()
    if ans < p[2]:
        ans += 1
    for i, j in ((-1, 0), (1, 0), (0, 1), (0, -1)):
        next_p = (p[0] + i, p[1] + j)
        if (0 <= next_p[0] < H) and (0 <= next_p[1] < W):
            if not m[next_p[0]][next_p[1]]:
                m[next_p[0]][next_p[1]] = 1
                queue_append((next_p[0], next_p[1], ans+1))
print(ans)


# Fixed version:
import sys
from collections import deque
input = sys.stdin.readline

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

m = [list(map(lambda x: 1 if x=="#" else 0, input())) for _ in range(H)]
black = [(i, j, 0) for i in range(H) for j in range(W) if m[i][j] == 1]

# print(m)
# print(black)

queue = deque(black)
queue_append = queue.append
ans = 0
while queue:
    p = queue.popleft()
    if ans < p[2]:
        ans += 1
    for i, j in ((-1, 0), (1, 0), (0, 1), (0, -1)):
        next_p = (p[0] + i, p[1] + j)
        if (0 <= next_p[0] < H) and (0 <= next_p[1] < W):
            if not m[next_p[0]][next_p[1]]:
                m[next_p[0]][next_p[1]] = 1
                queue_append((next_p[0], next_p[1], ans+1))
print(ans)

# Buggy version:
from collections import deque


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

visited = [[False]*w for i in range(h)]
q = deque([])
for i in range(h):
    for j in range(w):
        if a[i][j] == "#":
            q.append((i, j, 0))
            visited[i][j] = True
ans = 0
while q:
    i, j, times = q.popleft()
    ans = max(times, ans)

    for next_i, next_j in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:
        if 0 <= next_i < h and 0 <= next_j < w and not visited[next_i][next_j]:
            visited[i][j] = True
            q.append((next_i, next_j, times + 1))
print(ans)

# Fixed version:
import sys
from collections import deque


input = sys.stdin.readline
h, w = map(int, input().split())
a = [input() for i in range(h)]

visited = [[False]*w for i in range(h)]
q = deque([])
for i in range(h):
    for j in range(w):
        if a[i][j] == "#":
            q.append((i, j, 0))
            visited[i][j] = True
ans = 0
while q:
    i, j, times = q.popleft()
    ans = max(times, ans)
    for next_i, next_j in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:
        if 0 <= next_i < h and 0 <= next_j < w and not visited[next_i][next_j]:
            visited[next_i][next_j] = True
            q.append((next_i, next_j, times + 1))
print(ans)

# Buggy version:
from collections import deque
import sys
#input=sys.stdin.readline
H,W=map(int,input().split())
maze=[list(input()) for i in range(H)]

#-------------------------------------------------------------------------
#白から黒に変えていく

def search() :
    
    pos=deque([])

    D= [[True]*(W+2)]                                  #True True True True
    D+=[[True]+[False]*W+[True] for i in range(H)]     #True FalseFalseTrue
    D.append([True]*(W+2))                             #True True True True

    for i in range(H) :
        for j in range(W) :
            if maze[i][j]=="#" :
                pos.append([i+1,j+1,0])
                D[i+1][j+1]=True
 
    while len(pos)>0 :                             #forではなく各if構文だと通った…
        h,w,depth=pos.popleft()
        if not D[h+1][w] :
            pos.append([h+1,w,depth+1])
            D[h+1][w]=True

        if not D[h-1][w] :
            pos.append([h-1,w,depth+1])
            D[h-1][w]=True

        if not D[h][w+1] :
            pos.append([h,w+1,depth+1])
            D[h][w+1]=True

        if not D[h][w-1] :
            pos.append([h,w-1,depth+1])
            D[h][w-1]=True

    return depth            

print(search())


# Fixed version:
from collections import deque
import sys
input=sys.stdin.readline


#-------------------------------------------------------------------------
#白から黒に変えていく

def search() :
    H,W=map(int,input().split())
    pos=deque([])

    D= [[True]*(W+2)]                                  #True True True True
    D+=[[True]+[False]*W+[True] for i in range(H)]     #True FalseFalseTrue
    D.append([True]*(W+2))                             #True True True True

    for i in range(H) :
        maze=input()
        for j in range(W) :
            if maze[j]=="#" :
                pos.append([i+1,j+1,0])
                D[i+1][j+1]=True
 
    while len(pos)>0 :                             #forではなく各if構文だと通った…
        h,w,depth=pos.popleft()
        if not D[h+1][w] :
            pos.append([h+1,w,depth+1])
            D[h+1][w]=True

        if not D[h-1][w] :
            pos.append([h-1,w,depth+1])
            D[h-1][w]=True

        if not D[h][w+1] :
            pos.append([h,w+1,depth+1])
            D[h][w+1]=True

        if not D[h][w-1] :
            pos.append([h,w-1,depth+1])
            D[h][w-1]=True

    return depth            

print(search())

# Buggy version:
H, W = map(int, input().split())
map = [list(input()) for _ in range(H)]
from collections import deque

que = deque()
seen = [[-1]*W for _ in range(H)]
max = 0

for i in range(H):
    for j in range(W):
        if map[i][j] == "#":
            que.append([i,j])
            seen[i][j] = 0

while que:
    y, x = que.popleft()
    for dy, dx in ([0,1],[0,-1],[1,0],[-1,0]):
        ny = y + dy
        nx = x + dx
        if 0<=ny<H and 0<=nx<W and seen[ny][nx]==-1:
            seen[ny][nx] = seen[y][x] + 1
            que.append([ny,nx])
            if max < seen[ny][nx]:
                max = seen[ny][nx]

print(max)


# Fixed version:
import sys
input = sys.stdin.readline
H, W = map(int, input().split())
map = [list(input()) for _ in range(H)]
from collections import deque

que = deque()
seen = [[-1]*W for _ in range(H)]
max = 0



for i in range(H):
    for j in range(W):
        if map[i][j] == "#":
            que.append([i,j])
            seen[i][j] = 0

while que:
    #print(que)
    y, x = que.popleft()
    for dy, dx in ([0,1],[0,-1],[1,0],[-1,0]):
        ny = y + dy
        nx = x + dx
        if 0<=ny<H and 0<=nx<W and seen[ny][nx]==-1:
            seen[ny][nx] = seen[y][x] + 1
            que.append([ny,nx])
            if max < seen[ny][nx]:
                max = seen[ny][nx]

print(max)

# Buggy version:
h,w=map(int,input().split())
a=['*'*(w+2)]+['*'+input()+'*' for _ in range(h)]+['*'*(w+2)]
from collections import deque
d=deque()
c=[[0]*w for _ in range(h)]
for i in range(1,h+1):
  for j in range(1,w+1):
    if a[i][j]=='#':
      d.append([i,j])
      c[i-1][j-1]=1
di=[[0,1],[1,0],[-1,0],[0,-1]]
while d:
  g=d.popleft()
  for i in di:
    x=g[0]+i[0]
    y=g[1]+i[1]
    if a[x][y]=='.':
      if c[x-1][y-1]==0:
        d.append([x,y])
        c[x-1][y-1]=c[g[0]-1][g[1]-1]+1
m=0
for i in range(h-1):
  for j in range(w-1):
    m=max(m,c[i][j])
print(m)

# Fixed version:
h,w=map(int,input().split())
a=['*'*(w+2)]+['*'+input()+'*' for _ in range(h)]+['*'*(w+2)]
from collections import deque
d=deque()
c=[[0]*w for _ in range(h)]
for i in range(1,h+1):
  for j in range(1,w+1):
    if a[i][j]=='#':
      d.append([i,j])
di=[[0,1],[1,0],[-1,0],[0,-1]]
while d:
  g=d.popleft()
  for i in di:
    x=g[0]+i[0]
    y=g[1]+i[1]
    if a[x][y]=='.':
      if c[x-1][y-1]==0:
        d.append([x,y])
        c[x-1][y-1]=c[g[0]-1][g[1]-1]+1
m=0
for i in range(h):
  for j in range(w):
    m=max(m,c[i][j])
print(m)

# Buggy version:
from collections import deque
r, c = list(map(int, input().split()))
sy, sx = [0, 0]
gy, gx = [r-1, c-1]

s = [list(map(str, list(input()))) for i in range(r)]

N = r*c
G = [[] for _ in range(N)]
dist = [-1]*N
que = deque()
for i in range(r):
    for j in range(c):
        if s[i][j] == '#':
            que.append(i*c+j)
            dist[i*c+j] = 0
        for x, y in ([0, 1], [0, -1], [1, 0], [-1, 0]):
            if 0 <= i+y <= r-1 and 0 <= j+x <= c-1:
                G[i*c+j].append((i+y)*c+j+x)

while que:
    v = que.popleft()
    d = dist[v]
    for w in G[v]:
        if dist[w] > -1:
            continue
        dist[w] = d + 1
        que.append(w)

ans = max(dist)
print(ans)


# Fixed version:
from collections import deque
import sys
input = sys.stdin.readline

r, c = list(map(int, input().split()))
sy, sx = [0, 0]
gy, gx = [r-1, c-1]

s = [list(map(str, list(input()))) for i in range(r)]

N = r*c
G = [[] for _ in range(N)]
dist = [-1]*N
que = deque()
for i in range(r):
    for j in range(c):
        if s[i][j] == '#':
            que.append(i*c+j)
            dist[i*c+j] = 0


while que:
    v = que.popleft()
    d = dist[v]
    for x, y in ([0, 1], [0, -1], [1, 0], [-1, 0]):
        if 0 <= v//c+y <= r-1 and 0 <= (v % c)+x <= c-1:
            w = v+y*c+x
            if dist[w] > -1:
                continue
            dist[w] = d + 1
            que.append(w)

ans = max(dist)
print(ans)

# Buggy version:
from collections import deque
import sys
input=sys.stdin.readline
h,w=map(int,input().split())
d=deque()
dc=0
b=[]
for i in range(h):
  s=input()
  for j in range(w):
    if s[j]=="#":d.append([i,j]);dc+=1
  b.append(list(s))
count=0
while dc!=0:
  dc=0
  for i in range(dc):
    x=d.popleft()
    if x[0]<h-1:
      if b[x[0]+1][x[1]]==".":b[x[0]+1][x[1]]=count;d.append([x[0]+1,x[1]]);dc+=1
    if 0<x[0]:
      if b[x[0]-1][x[1]]==".":b[x[0]-1][x[1]]=count;d.append([x[0]-1,x[1]]);dc+=1
    if x[1]<w-1:
      if b[x[0]][x[1]+1]==".":b[x[0]][x[1]+1]=count;d.append([x[0],x[1]+1]);dc+=1
    if 0<x[1]:
      if b[x[0]][x[1]-1]==".":b[x[0]][x[1]-1]=count;d.append([x[0],x[1]-1]);dc+=1
  count+=1
print(count-1) 

# Fixed version:
from collections import deque
import sys
input=sys.stdin.readline
h,w=map(int,input().split())
d=deque()
dc=0
b=[]
for i in range(h):
  t=[]
  s=input()
  for j in range(w):
    if s[j]=="#":d.append((i,j));dc+=1;t.append(1)
    else:t.append(0)
  b.append(t)
count=0
while dc!=0:
  ld=dc
  dc=0
  for i in range(ld):
    x=d.popleft()
    if x[0]<h-1:
      if b[x[0]+1][x[1]]==0:b[x[0]+1][x[1]]=1;d.append((x[0]+1,x[1]));dc+=1
    if 0<x[0]:
      if b[x[0]-1][x[1]]==0:b[x[0]-1][x[1]]=1;d.append((x[0]-1,x[1]));dc+=1
    if x[1]<w-1:
      if b[x[0]][x[1]+1]==0:b[x[0]][x[1]+1]=1;d.append((x[0],x[1]+1));dc+=1
    if 0<x[1]:
      if b[x[0]][x[1]-1]==0:b[x[0]][x[1]-1]=1;d.append((x[0],x[1]-1));dc+=1
  count+=1
print(count-1)

# Buggy version:
from collections import deque
import sys
input=sys.stdin.readline


def BFS():
    point=0
    color=[["white" for _ in range(w)] for _ in range(h)]
    D=[[0 for _ in range(w)] for _ in range(h)]

    queue=deque([])
    for i in range(h):
        for j in range(w):
            if A[i][j]=="#":
                queue.append([i,j])
                D[i][j]=0

    while len(queue)>0:
        x,y=queue.popleft()
        for a,b in [[1,0],[-1,0],[0,1],[0,-1]]:
            X,Y=x+a,y+b
            if 0<=X<h and 0<=Y<w:
                if color[X][Y]!="black":
                    color[X][Y]="gray"
                    D[X][Y]=D[x][y]+1
                    point=max(point,D[X][Y])
                    queue.append([X,Y])
        color[x][y]="black"

    return point


h,w=map(int,input().split())
A=[list(input()) for _ in range(h)]
print(BFS())

# Fixed version:
from collections import deque
import sys
input=sys.stdin.readline


def BFS():
    point=0
    color=[["white" for _ in range(w)] for _ in range(h)]
    D=[[0 for _ in range(w)] for _ in range(h)]

    queue=deque([])
    for i in range(h):
        for j in range(w):
            if A[i][j]=="#":
                color[i][j]="gray"
                queue.append([i,j])
                D[i][j]=0

    while len(queue)>0:
        x,y=queue.popleft()
        for a,b in [[1,0],[-1,0],[0,1],[0,-1]]:
            X,Y=x+a,y+b
            if 0<=X<h and 0<=Y<w:
                if color[X][Y]=="white":
                    color[X][Y]="gray"
                    D[X][Y]=D[x][y]+1
                    point=max(point,D[X][Y])
                    queue.append([X,Y])
        color[x][y]="black"

    return point


h,w=map(int,input().split())
A=[list(input()) for _ in range(h)]
print(BFS())

# Buggy version:
from collections import deque
import sys
input = sys.stdin.readline
q = deque()
h, w = map(int, input().split())
a = [list(input()) for _ in range(h)]
x = ((-1, 0), (1, 0), (0, -1), (0, 1))
for i in range(h):
    for j in range(w):
        if a[i][j] == "#":
            for k in x:
                if 0 <= i + k[0] < h and 0 <= j + k[1] < w and a[i + k[0]][j + k[1]] == ".":
                    a[i + k[0]][j + k[1]] = "0"
                    q.append([i + k[0], j + k[1], 1])
ans = 0
while q:
    u, v, res = q.popleft()
    for k in x:
        if 0 <= u + k[0] < h and 0 <= v + k[1] < w and a[u + k[0]][v + k[1]] == ".":
            a[u + k[0]][v + k[1]] = "0"
            q.append((u + k[0], v + k[1], res + 1))
print(res+1)

# Fixed version:
from collections import deque 
import sys
input = sys.stdin.readline
q = deque([])
h,w=map(int,input().split())
a=[list(input()) for i in range(h)]
x=[[-1,0],[1,0],[0,-1],[0,1]]
for i in range(h):
    for j in range(w):
        if a[i][j]=="#":
            for k in x:
                if 0<=i+k[0]<h and 0<=j+k[1]<w and a[i+k[0]][j+k[1]]==".":
                    a[i+k[0]][j+k[1]]="0"
                    q.append([i+k[0],j+k[1],1])
ans=0
while q:
    v=q.popleft()
    for k in x:
        if 0<=v[0]+k[0]<h and 0<=v[1]+k[1]<w and a[v[0]+k[0]][v[1]+k[1]]==".":
            a[v[0]+k[0]][v[1]+k[1]]="0"
            q.append([v[0]+k[0],v[1]+k[1],v[2]+1])
            ans=v[2]+1
print(ans)

# Buggy version:
import sys
from collections import deque
input = sys.stdin.readline

H,W = map(int,input().split())
D = [list(input()) for i in range(H)]
ans = 0

for i in range(H):
    for j in range(W):
        sy = i
        sx = j
        if D[sy][sx] == ".":
            Q = deque()
            Q.append((sx,sy))
            dist = [[-1]*W for i in range(H)]
            dist[sy][sx] = 0
            dx = [1,0,-1,0]
            dy = [0,-1,0,1]
            while Q:
                x,y = Q.popleft()
                if D[y][x] == "#":
                    d = dist[y][x]
                    ans = max(ans,d)
                    break
                for i in range(4):
                    nx = x+dx[i]
                    ny = y+dy[i]
                    if 0<=nx<=W-1 and 0<=ny<=H-1 and dist[ny][nx] == -1:
                        Q.append((nx,ny))
                        dist[ny][nx] = dist[y][x]+1

print(ans)

# Fixed version:
import sys
from collections import deque
input = sys.stdin.readline

H,W = map(int,input().split())
D = [list(input()) for i in range(H)]
ans = 0
dist = [[-1]*W for i in range(H)]
Q = deque()
dx = [1,0,-1,0]
dy = [0,-1,0,1]

for sy in range(H):
    for sx in range(W):
        if D[sy][sx] == "#":
            Q.append((sx,sy))
            dist[sy][sx] = 0
while Q:
    x,y = Q.popleft()
    for i in range(4):
        nx = x+dx[i]
        ny = y+dy[i]
        if 0<=nx<=W-1 and 0<=ny<=H-1 and dist[ny][nx] == -1 and D[ny][nx] == ".":
            Q.append((nx,ny))
            dist[ny][nx] = dist[y][x]+1

for y in range(H):
    for x in range(W):
        if D[y][x] == ".":
            ans = max(ans,dist[y][x])
print(ans)

# Buggy version:
from collections import deque
H, W = map(int, input().split())
C = []
Q = deque()
dist = [[-1]*W for i in range(H)]

for i in range(H):
  s = list(input())
  yxidx = [(i,x) for x,v in enumerate(s) if v == "#"]
  for (y, x) in yxidx:
    Q.append((y,x))
    dist[y][x] = 0
  C.append(s)
X = [1,0,-1,0]
Y = [0,-1,0,1]


while Q:
  y,x = Q.popleft()
  for i in range(4):
    nx = x + X[i]
    ny = y + Y[i]
    if (0 <= nx < W) and (0 <= ny < H) and (dist[ny][nx] == -1) and (C[ny][nx] != "#"):
      dist[ny][nx] = dist[y][x] + 1
      Q.append((ny,nx))
      print(ny,nx)

ans = 0
for i in range(H):
  ans = max(ans,max(dist[i]))
print(ans)


# Fixed version:
from collections import deque
H, W = map(int, input().split())
C = []
Q = deque()
dist = [[-1]*W for i in range(H)]

for i in range(H):
  s = list(input())
  yxidx = [(i,x) for x,v in enumerate(s) if v == "#"]
  for (y, x) in yxidx:
    Q.append((y,x))
    dist[y][x] = 0
  C.append(s)
X = [1,0,-1,0]
Y = [0,-1,0,1]


while Q:
  y,x = Q.popleft()
  for i in range(4):
    nx = x + X[i]
    ny = y + Y[i]
    if (0 <= nx < W) and (0 <= ny < H) and (dist[ny][nx] == -1):
      dist[ny][nx] = dist[y][x] + 1
      Q.append((ny,nx))

ans = 0
for i in range(H):
  ans = max(ans,max(dist[i]))
print(ans)

# Buggy version:
from collections import deque

h,w=map(int,input().split())
w+=2

a=[list('@'*w)]
for i in range(h):
    a+=[list('@'+input()+'@')]
a+=[list('@'*w)]
h+=2

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

def bfs(sx,sy):
    A[sx][sy]=0
    que=deque()
    que.append((sx,sy))

    while que:
        x,y=que.popleft()
        for dx,dy in xy:
            nx,ny=dx+x,dy+y
            tmp=A[x][y]+1
            if a[nx][ny]!='@':
                if A[nx][ny]<=tmp:continue
                A[nx][ny]=tmp
                que.append((nx,ny))


A=[[float('inf')]*w for i in range(h)]

res=0
for i in range(1,h-1):
    for j in range(1,w-1):
        if a[i][j]=='#':
            bfs(i,j)

S=A[1:-1]

for e in S:
    res=max(res,max(e[1:-1]))
print(res)


# Fixed version:
from collections import deque

h,w=map(int,input().split())
w+=2

a=[list('@'*w)]
for i in range(h):
    a+=[list('@'+input()+'@')]
a+=[list('@'*w)]
h+=2

xy=[(-1,0),(0,-1),(0,1),(1,0)]
que=deque()

def bfs():
    res=0
    while que:
        x,y=que.popleft()
        for dx,dy in xy:
            nx,ny=dx+x,dy+y
            tmp=A[x][y]+1
            if a[nx][ny]!='@':
                if A[nx][ny]<=tmp:continue
                A[nx][ny]=tmp
                que.append((nx,ny))
                res=max(res,tmp)
    return res


A=[[float('inf')]*w for i in range(h)]

res=0
for i in range(1,h-1):
    for j in range(1,w-1):
        if a[i][j]=='#':
            A[i][j]=0
            que.append((i,j))

res=bfs()
print(res)

# Buggy version:
from collections import deque

h,w = map(int, input().split())
# 場外を追加
A = [['*']*(w+2)] + [['*']+[s for s in input()]+['*'] for _ in range(h)] + [['*']*(w+2)]
visited = [[0]*(w+2) for _ in range(h+2)]

dq = deque()
n=0
directions = [[0,1],[1,0],[0,-1],[-1,0]]
# 初期配置の黒をキューに追加
for hi in range(1,h+1):
    for wi in range(1,w+1):
        if A[hi][wi] == '#':
            dq.append([hi,wi,n])

# キューが空になるまで
while dq:
    hi,wi,n = dq.popleft()
    visited[hi][wi] = 1

    for d in directions:
        new_hi, new_wi = hi+d[0],wi + d[1]
        # 「黒くしてない白マス」をキューに追加
        if visited[new_hi][new_wi] == 0 and A[new_hi][new_wi] == '.':
            dq.append([new_hi,new_wi,n+1])

print(n)

# Fixed version:
from collections import deque

h,w = map(int, input().split())
# 場外を追加
A = [['*']*(w+2)] + [['*']+[s for s in input()]+['*'] for _ in range(h)] + [['*']*(w+2)]
visited = [[0]*(w+2) for _ in range(h+2)]

dq = deque()
n=0
directions = [[0,1],[1,0],[0,-1],[-1,0]]
# 初期配置の黒をキューに追加
for hi in range(1,h+1):
    for wi in range(1,w+1):
        if A[hi][wi] == '#':
            dq.append([hi,wi,n])
            visited[hi][wi] = 1
# キューが空になるまで
while dq:
    hi,wi,n = dq.popleft()

    for d in directions:
        new_hi, new_wi = hi+d[0],wi + d[1]
        # 「黒くしてない白マス」をキューに追加
        if visited[new_hi][new_wi] == 0 and A[new_hi][new_wi] == '.':
            dq.append([new_hi,new_wi,n+1])
            visited[new_hi][new_wi] = 1
print(n)

# Buggy version:
from collections import deque


def bfs(S):  # 幅優先探索  # キュー
    dist = [-1] * (w * h)  # 前処理
    que = deque()
    for i, Si in enumerate(S):
        for j, Sij in enumerate(Si):
            if Sij == '#':
                dist[i + (w * j)] = 0
                que.append((i, j))

    while len(que) > 0:
        (x, y) = que.popleft()
        near = [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]
        for i, j in near:  # 移動先の候補
            if 0 <= i < h and 0 <= j < w and dist[i][j] < 0:
                dist[i + (w * j)] = dist[x + (w * y)] + 1
                que.append((i, j))
    return dist[x][y]


h, w = map(int, input().split())
a = [input() for _ in range(h)]
print(bfs(a))


# Fixed version:
from collections import deque


def bfs(S):  # 幅優先探索  # キュー
    dist = [[-1] * w for _ in range(h)]  # 前処理
    que = deque()
    for i, Si in enumerate(S):
        for j, Sij in enumerate(Si):
            if Sij == '#':
                dist[i][j] = 0
                que.append((i, j))

    while len(que) > 0:
        (x, y) = que.popleft()
        near = [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]
        for i, j in near:  # 移動先の候補
            if 0 <= i < h and 0 <= j < w and dist[i][j] < 0:
                dist[i][j] = dist[x][y] + 1
                que.append((i, j))
    return dist[x][y]


h, w = map(int, input().split())
a = [input() for _ in range(h)]
print(bfs(a))

# Buggy version:
from collections import deque
import sys
input = sys.stdin.readline
h,w=map(int, input().split(' '))
a = [input() for i in range(h)]
nl = [[] for i in range(h)]
q = deque()
for i in range(h):
    for j in range(w):
        if a[i][j] == "#":
            nl[i].append(0)
            q.append([i,j,0])
        else:
            nl[i].append(-1)
"""
while q:
    [s,t,cnt] = q.popleft()
    if s>0 and nl[s-1][t] == -1:
        q.append([s-1,t,cnt+1])
        nl[s-1][t] = cnt+1
    if s<h-1 and nl[s+1][t] == -1:
        q.append([s+1,t,cnt+1])
        nl[s+1][t] = cnt+1
    if t>0 and nl[s][t-1] == -1:
        q.append([s,t-1,cnt+1])
        nl[s][t-1] = cnt+1
    if t<w-1 and nl[s][t+1] == -1:
        q.append([s,t+1,cnt+1])
        nl[s][t+1] = cnt+1
ans = 0
for i in range(h):
    ans = max(ans,max(nl[i]))
print(ans)
"""

# Fixed version:
from collections import deque
import sys
input = sys.stdin.readline
h,w=map(int, input().split(' '))
a = [input() for i in range(h)]
nl = [[] for i in range(h)]
q = deque()
for i in range(h):
    for j in range(w):
        if a[i][j] == "#":
            nl[i].append(0)
            q.append([i,j,0])
        else:
            nl[i].append(-1)
while q:
    [s,t,cnt] = q.popleft()
    if s>0 and nl[s-1][t] == -1:
        q.append([s-1,t,cnt+1])
        nl[s-1][t] = cnt+1
    if s<h-1 and nl[s+1][t] == -1:
        q.append([s+1,t,cnt+1])
        nl[s+1][t] = cnt+1
    if t>0 and nl[s][t-1] == -1:
        q.append([s,t-1,cnt+1])
        nl[s][t-1] = cnt+1
    if t<w-1 and nl[s][t+1] == -1:
        q.append([s,t+1,cnt+1])
        nl[s][t+1] = cnt+1
ans = 0
for i in range(h):
    ans = max(ans,max(nl[i]))
print(ans)

# Buggy version:
from collections import deque

h, w = map(int,input().split())
alist = [input().strip() for i in range(h)]
dxy = [(0,1),(1,0),(0,-1),(-1,0)]

INF = 99999
dp = [[INF]*w for i in range(h)]
q = deque()
for y, row in enumerate(alist):
  for x, c in enumerate(row):
    if c=='#':
      dp[y][x] = 0
      q.append((x,y))

while q:
  x, y = q.popleft()
  d = dp[y][x]
  for dx, dy in dxy:
    nx, ny = x+dx, y+dy
    if not 0 <= nx < w:
      continue
    if not 0 <= ny < h:
      continue
    if dp[ny][nx] <= d+1:
      continue
    dp[ny][nx] = d+1
    q.append((nx,ny))
  print(dp)

print(max(max(row) for row in dp))


# Fixed version:
from collections import deque

h, w = map(int,input().split())
alist = [input().strip() for i in range(h)]
dxy = [(0,1),(1,0),(0,-1),(-1,0)]

INF = 99999
dp = [[INF]*w for i in range(h)]
q = deque()
for y, row in enumerate(alist):
  for x, c in enumerate(row):
    if c=='#':
      dp[y][x] = 0
      q.append((x,y))

while q:
  x, y = q.popleft()
  d = dp[y][x]
  for dx, dy in dxy:
    nx, ny = x+dx, y+dy
    if not 0 <= nx < w:
      continue
    if not 0 <= ny < h:
      continue
    if dp[ny][nx] <= d+1:
      continue
    dp[ny][nx] = d+1
    q.append((nx,ny))

print(max(max(row) for row in dp))

# Buggy version:
from collections import deque
from sys import stdin


def main():
    height, width = map(int, stdin.readline().split())
    q = deque([])
    grid = [stdin.readline() for _ in range(height)]
    distance = [[-1 for _ in range(width)] for _ in range(height)]
    for i in range(height):
        for j in range(width):
            if grid[i][j] == "#":
                q.append((i, j))
                distance[i][j] = 0
    answer = 0
    delta = ((0, 1), (1, 0), (0, -1), (-1, 0))
    while q:
        y, x = q.popleft()
        answer = distance[y][x]
        for dy, dx in delta:
            new_y = y + dy
            new_x = x + dx
            if 0 <= new_y < height and 0 <= new_x < width and grid[new_y][new_x] == ".":
                distance[new_y][new_x] = answer + 1
                grid[new_y][new_x] = "#"
                q.append((new_y, new_x))
    print(answer)


if __name__ == '__main__':
    main()



# Fixed version:
from collections import deque
from sys import stdin


def main():
    height, width = map(int, stdin.readline().split())
    q = deque([])
    grid = [stdin.readline() for _ in range(height)]
    distance = [[-1 for _ in range(width)] for _ in range(height)]
    for i in range(height):
        for j in range(width):
            if grid[i][j] == "#":
                q.append((i, j))
                distance[i][j] = 0
    answer = 0
    delta = ((0, 1), (1, 0), (0, -1), (-1, 0))
    while q:
        y, x = q.popleft()
        answer = distance[y][x]
        for dy, dx in delta:
            new_y = y + dy
            new_x = x + dx
            if 0 <= new_y < height and 0 <= new_x < width and distance[new_y][new_x] < 0:
                distance[new_y][new_x] = answer + 1
                q.append((new_y, new_x))
    print(answer)


if __name__ == '__main__':
    main()