Takahashi has a maze, which is a grid of H \times W squares with H horizontal rows and W vertical columns.
The square at the i-th row from the top and the j-th column is a "wall" square if S_{ij} is #, and a "road" square if S_{ij} is ..
From a road square, you can move to a horizontally or vertically adjacent road square.
You cannot move out of the maze, move to a wall square, or move diagonally.
Takahashi will choose a starting square and a goal square, which can be any road squares, and give the maze to Aoki.
Aoki will then travel from the starting square to the goal square, in the minimum number of moves required.
In this situation, find the maximum possible number of moves Aoki has to make.

-----Constraints-----
 - 1 \leq H,W \leq 20
 - S_{ij} is . or #.
 - S contains at least two occurrences of ..
 - Any road square can be reached from any road square in zero or more moves.

-----Input-----
Input is given from Standard Input in the following format:
H W
S_{11}...S_{1W}
:
S_{H1}...S_{HW}

-----Output-----
Print the maximum possible number of moves Aoki has to make.

-----Sample Input-----
3 3
...
...
...

-----Sample Output-----
4

If Takahashi chooses the top-left square as the starting square and the bottom-right square as the goal square, Aoki has to make four moves.

Difficulty: MEDIUM

Solutions:
from collections import deque
(h, w) = map(int, input().split())
a = [input() + '#' for _ in range(h)]
b = ['#' * (w + 1)]
r = 0
for i in range(h):
	for j in range(w):
		if a[i][j] == '.':
			b[:-1] = map(list, a)
			b[i][j] = 0
			q = deque([(i, j)])
			while q:
				(i, j) = q.popleft()
				r = max(r, b[i][j])
				d = 0
				for i1 in range(i - 1, i + 2):
					for j1 in range(j - d, j + 2, 2):
						if b[i1][j1] == '.':
							b[i1][j1] = b[i][j] + 1
							q.append((i1, j1))
					d ^= 1
print(r)


(h, w) = map(int, input().split())
m = []
for i in range(h):
	m.append(list(map(lambda x: int(x == '#'), list(input()))) + [1, 1])
m += [[1 for i in range(w + 2)]] * 2
mx = 0
d = [(1, 0), (-1, 0), (0, 1), (0, -1)]
for x in range(h):
	for y in range(w):
		if m[x][y]:
			continue
		s = [(x, y)]
		c = -1
		v = [[0 for i in range(w)] for i in range(h)]
		v[x][y] = 1
		while s:
			ns = []
			for i in s:
				for j in d:
					if m[i[0] + j[0]][i[1] + j[1]] or v[i[0] + j[0]][i[1] + j[1]]:
						continue
					v[i[0] + j[0]][i[1] + j[1]] = 1
					ns.append((i[0] + j[0], i[1] + j[1]))
			s = ns
			c += 1
		mx = max(mx, c)
print(mx)


from collections import deque
(h, w) = map(int, input().split())
maze = [input() for _ in range(h)]
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
res = 0
for sx in range(w):
	for sy in range(h):
		if maze[sy][sx] == '.':
			d = [[-1 for _ in range(w)] for _ in range(h)]
			que = deque([[sx, sy]])
			d[sy][sx] = 0
			while que:
				(x, y) = que.popleft()
				for i in range(4):
					nx = x + dx[i]
					ny = y + dy[i]
					if 0 <= nx < w and 0 <= ny < h and (d[ny][nx] == -1) and (maze[ny][nx] == '.'):
						que.append([nx, ny])
						d[ny][nx] = d[y][x] + 1
						if res < d[ny][nx]:
							res = d[ny][nx]
print(res)


import queue
(H, W) = map(int, input().split())
S = [list(input()) for _ in range(H)]
ans = 0
for sx in range(H):
	for sy in range(W):
		if S[sx][sy] == '#':
			continue
		D = [[float('inf') for _ in range(W)] for _ in range(H)]
		D[sx][sy] = 0
		q = queue.Queue()
		q.put((sx, sy))
		vs = [(1, 0), (0, 1), (-1, 0), (0, -1)]
		while not q.empty():
			(x, y) = q.get()
			for (dx, dy) in vs:
				nx = x + dx
				ny = y + dy
				if 0 <= nx < H and 0 <= ny < W and (S[nx][ny] != '#') and (D[nx][ny] == float('inf')):
					q.put((nx, ny))
					D[nx][ny] = D[x][y] + 1
		for gx in range(H):
			for gy in range(W):
				if S[gx][gy] == '#':
					continue
				ans = max(ans, D[gx][gy])
print(ans)


(H, W) = list(map(int, input().split()))
l = [list(input()) for i in range(H)]
l_count = [[0] * W for i in range(H)]
from collections import deque

def answer(st_X, st_Y):
	(tmp_X, tmp_Y) = (st_X, st_Y)
	que = deque([[tmp_X, tmp_Y]])
	after = set()
	while que:
		(tmp_X, tmp_Y) = que.popleft()
		nu = l_count[tmp_Y][tmp_X]
		after.add((tmp_X, tmp_Y))
		if tmp_X > 0 and l[tmp_Y][tmp_X - 1] == '.' and ((tmp_X - 1, tmp_Y) not in after) and ([tmp_X - 1, tmp_Y] not in que):
			l_count[tmp_Y][tmp_X - 1] = nu + 1
			que.append([tmp_X - 1, tmp_Y])
		if tmp_Y > 0 and l[tmp_Y - 1][tmp_X] == '.' and ((tmp_X, tmp_Y - 1) not in after) and ([tmp_X, tmp_Y - 1] not in que):
			l_count[tmp_Y - 1][tmp_X] = nu + 1
			que.append([tmp_X, tmp_Y - 1])
		if tmp_X < W - 1 and l[tmp_Y][tmp_X + 1] == '.' and ((tmp_X + 1, tmp_Y) not in after) and ([tmp_X + 1, tmp_Y] not in que):
			l_count[tmp_Y][tmp_X + 1] = nu + 1
			que.append([tmp_X + 1, tmp_Y])
		if tmp_Y < H - 1 and l[tmp_Y + 1][tmp_X] == '.' and ((tmp_X, tmp_Y + 1) not in after) and ([tmp_X, tmp_Y + 1] not in que):
			l_count[tmp_Y + 1][tmp_X] = nu + 1
			que.append([tmp_X, tmp_Y + 1])
ans = 0
for i in range(H):
	for j in range(W):
		if l[i][j] == '.':
			l_count = [[0] * W for i in range(H)]
			answer(j, i)
			tmp = max(sum(l_count, []))
			ans = max(ans, tmp)
print(ans)


import copy
(H, W) = map(int, input().split())
MAZE = [0] * H
for i in range(H):
	MAZE[i] = list(str(input()))
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

def solve_maze(sy, sx):
	MAZE1 = copy.deepcopy(MAZE)
	MAZE1[sy][sx] = '#'
	queue = []
	queue.append([sy, sx])
	d = [[100000000] * W for i in range(H)]
	d[sy][sx] = 0
	while len(queue) > 0:
		Q = queue.pop(0)
		move = d[Q[0]][Q[1]]
		for j in range(4):
			y = Q[0] + dy[j]
			x = Q[1] + dx[j]
			if 0 <= y <= H - 1 and 0 <= x <= W - 1 and (MAZE1[y][x] == '.'):
				queue.append([y, x])
				MAZE1[y][x] = '#'
				d[y][x] = move + 1
	return move
d_max = 0
for i in range(H):
	for j in range(W):
		if MAZE[i][j] == '.':
			d = solve_maze(i, j)
			if d > d_max:
				d_max = d
print(d_max)


(h, w) = map(int, input().split())
s = ['#' * (w + 2)]
s += ['#' + input() + '#' for _ in range(h)]
s.append('#' * (w + 2))
h += 2
w += 2
p = [[1, 0], [0, 1], [-1, 0], [0, -1]]
st = []
cnt = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '.':
			st.append((i, j))
			cnt += 1
ans = 0
for i in range(cnt):
	n = [st[i]]
	route = {n[0]: 0}
	c = 1
	count = 1
	while c < cnt:
		n2 = []
		for i in n:
			for j in p:
				np = (i[0] + j[0], i[1] + j[1])
				if s[np[0]][np[1]] == '.' and route.get(np, -1) == -1:
					n2.append(np)
					route[np] = count
					c += 1
		n = n2
		count += 1
	ans = max(ans, count - 1)
print(ans)


import queue

def main():
	(h, w) = list(map(int, input().split()))
	st = [[1] * (w + 2) for _ in range(h + 2)]
	for i in range(h):
		s = input()
		for j in range(w):
			if s[j] == '.':
				st[i + 1][j + 1] = 0
	ans = 0
	for i in range(1, h + 2):
		for j in range(1, w + 2):
			if st[i][j] == 0:
				fs = [[float('inf')] * (w + 2) for _ in range(h + 2)]
				q = queue.Queue()
				fs[i][j] = 0
				q.put([i, j])
				while not q.empty():
					(y, x) = q.get()
					if st[y - 1][x] == 0 and fs[y - 1][x] > fs[y][x] + 1:
						fs[y - 1][x] = fs[y][x] + 1
						q.put([y - 1, x])
					if st[y + 1][x] == 0 and fs[y + 1][x] > fs[y][x] + 1:
						fs[y + 1][x] = fs[y][x] + 1
						q.put([y + 1, x])
					if st[y][x - 1] == 0 and fs[y][x - 1] > fs[y][x] + 1:
						fs[y][x - 1] = fs[y][x] + 1
						q.put([y, x - 1])
					if st[y][x + 1] == 0 and fs[y][x + 1] > fs[y][x] + 1:
						fs[y][x + 1] = fs[y][x] + 1
						q.put([y, x + 1])
					if ans < fs[y][x]:
						ans = fs[y][x]
	print(ans)

def __starting_point():
	main()
__starting_point()


(H, W) = map(int, input().split())
S = [None] * W
S = [list(input()) for i in range(H)]
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]

def max_distance(i, j):
	not_visit = [[-1] * W for i in range(H)]
	not_visit[i][j] = 0
	stack = [(i, j)]
	while stack != []:
		(y, x) = stack.pop(0)
		for i in range(4):
			if 0 <= x + dx[i] < W and 0 <= y + dy[i] < H and (S[y + dy[i]][x + dx[i]] != '#') and (not_visit[y + dy[i]][x + dx[i]] == -1):
				not_visit[y + dy[i]][x + dx[i]] = not_visit[y][x] + 1
				stack.append((y + dy[i], x + dx[i]))
	return not_visit[y][x]
ans = 0
for i in range(H):
	for j in range(W):
		if S[i][j] != '#':
			ans = max(ans, max_distance(i, j))
print(ans)


INF = 10 ** 9 + 7
(H, W) = map(int, input().split())
S = list()
q = list()
S.append(['#'] * (W + 2))
for i in range(H):
	S.append(['#'] + list(input()) + ['#'])
S.append(['#'] * (W + 2))
m = 0
for y in range(1, H + 1):
	for x in range(1, W + 1):
		if S[y][x] == '#':
			continue
		D = [[INF] * (W + 2) for _ in range(H + 2)]
		D[y][x] = 0
		q.clear()
		q.append([x, y])
		while len(q) > 0:
			c = list(q.pop(0))
			for (dx, dy) in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
				(ny, nx) = (c[1] + dy, c[0] + dx)
				if S[ny][nx] == '.' and D[ny][nx] == INF:
					D[ny][nx] = D[c[1]][c[0]] + 1
					q.append([nx, ny])
					m = max(m, D[ny][nx])
print(m)


(H, W) = map(int, input().split())
s = [input() for _ in range(H)]
G = [['#'] * (W + 2) for _ in range(H + 2)]
for i in range(H):
	for j in range(W):
		G[i + 1][j + 1] = s[i][j]

def search(y, x):
	q = [(y, x)]
	d = [[-1] * (W + 2) for _ in range(H + 2)]
	d[y][x] = 0
	while q:
		(y1, x1) = q.pop(0)
		for (y2, x2) in ((y1 + 1, x1), (y1, x1 + 1), (y1 - 1, x1), (y1, x1 - 1)):
			if G[y2][x2] == '.' and d[y2][x2] == -1:
				d[y2][x2] = d[y1][x1] + 1
				q.append((y2, x2))
	return max((max(_) for _ in d))
ans = 0
for i in range(H):
	for j in range(W):
		if G[i + 1][j + 1] == '.':
			ans = max(search(i + 1, j + 1), ans)
print(ans)


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

def bfs(i, j, d):
	d_max = 0
	used = [[False for j in range(W)] for i in range(H)]
	Q = deque()
	Q.append((i, j, d))
	used[i][j] = True
	while Q:
		(i, j, d) = Q.popleft()
		for (ni, nj) in ((i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)):
			if ni < 0 or nj < 0 or ni >= H or (nj >= W):
				continue
			if M[ni][nj] == '.' and (not used[ni][nj]):
				d_max = max(d_max, d + 1)
				used[ni][nj] = True
				Q.append((ni, nj, d + 1))
	return d_max
ans = 0
for i in range(H):
	for j in range(W):
		if M[i][j] == '.':
			ans = max(ans, bfs(i, j, 0))
print(ans)


from collections import deque
(h, w) = map(int, input().split())
s = [list(input()) for _ in range(h)]
sl = []
flag = False
for i in range(h):
	for j in range(w):
		if s[i][j] == '.':
			sl.append([i, j])
q = deque()
dire = [(0, 1), (0, -1), (1, 0), (-1, 0)]
ans = 0
for (sh, sw) in sl:
	c = [[0] * w for _ in range(h)]
	q.append((sh, sw, 0))
	while q:
		(ph, pw, k) = q.pop()
		if c[ph][pw] == 0:
			ans = max(ans, k)
			c[ph][pw] = 1
			for (dh, dw) in dire:
				(hdh, wdw) = (ph + dh, pw + dw)
				if 0 <= hdh < h and 0 <= wdw < w and (c[hdh][wdw] == 0):
					if s[hdh][wdw] == '.':
						q.appendleft((hdh, wdw, k + 1))
print(ans)


from collections import deque
(H, W) = map(int, input().split())
maze = [list(input()) for _ in range(H)]
dxy = [[-1, 0], [0, 1], [1, 0], [0, -1]]
ans = 0
for h in range(H):
	for w in range(W):
		if maze[h][w] == '#':
			continue
		d_maze = [[-1] * W for _ in range(H)]
		d_maze[h][w] = 0
		p = deque([[h, w]])
		while p:
			(rh, rw) = p.popleft()
			for (i, j) in dxy:
				nh = rh + i
				nw = rw + j
				if 0 <= nh < H and 0 <= nw < W and (maze[nh][nw] == '.') and (d_maze[nh][nw] == -1):
					d_maze[nh][nw] = d_maze[rh][rw] + 1
					p.append([nh, nw])
		ans = max(ans, max([max(l) for l in d_maze]))
print(ans)


import collections
(h, w) = map(int, input().split())
s = [input() for _ in range(h)]

def bfs(sx, sy):
	q = collections.deque([(sx, sy)])
	checked = [[0 for _ in range(w)] for _ in range(h)]
	checked[i][j] = 1
	res = 0
	while q:
		(qx, qy) = q.popleft()
		for (dx, dy) in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
			x = qx + dx
			y = qy + dy
			if 0 <= x < h and 0 <= y < w and (s[x][y] == '.') and (checked[x][y] == 0):
				q.append((x, y))
				checked[x][y] = checked[qx][qy] + 1
				res = max(checked[x][y], res)
	return res
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '.':
			ans = max(ans, bfs(i, j) - 1)
print(ans)


from collections import deque
import sys
import copy
N_MAX = 200000 + 5
INF = 10 ** 9 + 7
sys.setrecursionlimit(N_MAX)
MOD = 10 ** 9 + 7
nextH = [0, 1, 0, -1]
nextW = [1, 0, -1, 0]

def bfs(u, S):
	S[u[0]][u[1]] = 0
	q = deque()
	q.append(u)
	m = 0
	while q:
		u = q.popleft()
		for (h, w) in zip(nextH, nextW):
			h += u[0]
			w += u[1]
			if not (0 <= h < len(S) and 0 <= w < len(S[0])):
				continue
			if S[h][w] == '.':
				S[h][w] = S[u[0]][u[1]] + 1
				m = max(m, S[h][w])
				q.append((h, w))
	return m

def main():
	(H, W) = list(map(int, sys.stdin.readline().rstrip().split()))
	S = []
	for _ in range(H):
		S.append([x for x in sys.stdin.readline().rstrip()])
	m = 0
	for h in range(H):
		for w in range(W):
			D = copy.deepcopy(S)
			if S[h][w] == '.':
				m = max(m, bfs((h, w), D))
	print(m)
main()


from collections import deque

def bfs(loc):
	global ans
	d = [[float('inf')] * w for i in range(h)]
	dx = [1, 0, -1, 0]
	dy = [0, 1, 0, -1]
	que = deque([])
	que.append(loc)
	d[loc[0]][loc[1]] = 0
	while que:
		p = que.popleft()
		for i in range(4):
			nx = p[0] + dx[i]
			ny = p[1] + dy[i]
			if 0 <= nx < h and 0 <= ny < w and (maze[nx][ny] == '.') and (d[nx][ny] == float('inf')):
				d[nx][ny] = d[p[0]][p[1]] + 1
				que.append([nx, ny])
				if ans < d[nx][ny]:
					ans = d[nx][ny]
	return ans
(h, w) = map(int, input().split())
maze = [list(input()) for i in range(h)]
a = 0
ans = 0
loc = []
for i in range(h):
	for j in range(w):
		if maze[i][j] != '#':
			loc = [i, j]
		else:
			continue
		a = max(a, bfs(loc))
print(a)


def MI():
	return map(int, input().split())
from collections import deque

def bfs(field, s):
	q = deque([(0, s)])
	MOVE = [(-1, 0), (0, -1), (1, 0), (0, 1)]
	dist = [[-1] * W for i in range(H)]
	(d, i, j) = (-1, -1, -1)
	while q:
		(d, (i, j)) = q.popleft()
		if dist[i][j] != -1:
			continue
		dist[i][j] = d
		for (di, dj) in MOVE:
			ni = i + di
			nj = j + dj
			if not 0 <= ni < H or not 0 <= nj < W:
				continue
			if field[ni][nj] == '#':
				continue
			if dist[ni][nj] != -1:
				continue
			q.append((d + 1, (ni, nj)))
	return (d, i, j)
(H, W) = MI()
field = [input() for _ in range(H)]
ans = 0
for i in range(H):
	for j in range(W):
		if field[i][j] == '.':
			(d, i, j) = bfs(field, (i, j))
			ans = max(ans, d)
print(ans)


from collections import deque
(h, w) = map(int, input().split())
a = ''.join((input() + '#' for _ in range(h)))
n = len(a)
b = ['#'] * w
q = deque()
r = 0
for i in range(n):
	if a[i] == '.':
		b[:-w] = a
		b[i] = 0
		q.append(i)
		while q:
			i = q.popleft()
			r = max(r, b[i])
			for j in (-1, 1, -w - 1, w + 1):
				j += i
				if b[j] == '.':
					b[j] = b[i] + 1
					q.append(j)
print(r)


from collections import deque
(H, W) = list(map(int, input().split()))
maze = [list(input()) for i in range(H)]

def bfs(sx, sy):
	result = 0
	count = [[-1] * W for i in range(H)]
	count[sx][sy] = 0
	d = deque()
	d.append((sx, sy))
	while d:
		(x, y) = d.popleft()
		result = count[x][y]
		for (i, j) in ([1, 0], [0, 1], [-1, 0], [0, -1]):
			(tx, ty) = (x + i, y + j)
			if not 0 <= tx < H or not 0 <= ty < W or maze[tx][ty] == '#' or (count[tx][ty] != -1):
				continue
			else:
				count[tx][ty] = count[x][y] + 1
				d.append((tx, ty))
	return result
ans = 0
for i in range(W):
	for j in range(H):
		if maze[j][i] == '.':
			ans = max(ans, bfs(j, i))
print(ans)


from collections import deque
(h, w) = map(int, input().split())
ma = [['#' for _ in range(w + 2)] for _ in range(h + 2)]
for i in range(h):
	tmp = list(input())
	for j in range(w):
		ma[i + 1][j + 1] = tmp[j]
ans = 0
for i in range(1, h + 1):
	for j in range(1, w + 1):
		if ma[i][j] == '#':
			continue
		elif ma[i][j] == '.':
			p = [[-1 for _ in range(w + 2)] for _ in range(h + 2)]
			p[i][j] = 0
			q = deque()
			q.append([i, j])
			while q:
				(y, x) = q.popleft()
				if ma[y + 1][x] == '.' and p[y + 1][x] == -1:
					p[y + 1][x] = p[y][x] + 1
					q.append([y + 1, x])
				if ma[y - 1][x] == '.' and p[y - 1][x] == -1:
					p[y - 1][x] = p[y][x] + 1
					q.append([y - 1, x])
				if ma[y][x + 1] == '.' and p[y][x + 1] == -1:
					p[y][x + 1] = p[y][x] + 1
					q.append([y, x + 1])
				if ma[y][x - 1] == '.' and p[y][x - 1] == -1:
					p[y][x - 1] = p[y][x] + 1
					q.append([y, x - 1])
			for l in range(1, h + 1):
				ans = max(ans, max(p[l]))
print(ans)


(H, W) = list(map(int, input().split()))
maze = [input() for i in range(H)]
direction = [(0, 1), (1, 0), (-1, 0), (0, -1)]

def bfs(sy, sx):
	reached = [[-1] * W for _ in range(H)]
	reached[sy][sx] = 0
	from collections import deque
	que = deque([[sy, sx]])
	while que:
		(iy, ix) = que.popleft()
		for d in direction:
			(tx, ty) = (ix + d[0], iy + d[1])
			if tx >= W or ty >= H or tx < 0 or (ty < 0):
				continue
			if reached[ty][tx] != -1 or maze[ty][tx] == '#':
				continue
			reached[ty][tx] = reached[iy][ix] + 1
			que.append([ty, tx])
	d_max = 0
	for i in range(H):
		for j in range(W):
			d_max = max(d_max, reached[i][j])
	return d_max
ans = 0
for i in range(H):
	for j in range(W):
		if maze[i][j] == '.':
			ans = max(ans, bfs(i, j))
print(ans)


import queue
(h, w) = map(int, input().split())
s = [input() for _ in range(h)]
INF = 10 ** 18
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '#':
			continue
		d = [[INF] * w for _ in range(h)]
		d[i][j] = 0
		q = queue.Queue()
		q.put((i, j))
		while not q.empty():
			(x, y) = q.get()
			for k in range(4):
				nx = x + dx[k]
				ny = y + dy[k]
				if 0 <= nx < h and 0 <= ny < w:
					if s[nx][ny] == '.' and d[nx][ny] == INF:
						q.put((nx, ny))
						d[nx][ny] = d[x][y] + 1
						ans = max(ans, d[nx][ny])
print(ans)


from collections import deque
(H, W) = map(int, input().split())
L = []
for _ in range(H):
	s = input()
	a = []
	for i in range(len(s)):
		a.append(s[i])
	L.append(a)
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]

def bfs(x, y):
	dp = [[10000000] * W for _ in range(H)]
	dp[y][x] = 0
	if L[y][x] == '#':
		return dp
	else:
		d = deque()
		d.append([x, y])
		while len(d) > 0:
			s = d.popleft()
			for i in range(4):
				if s[1] + dy[i] >= 0 and s[1] + dy[i] < H and (s[0] + dx[i] >= 0) and (s[0] + dx[i] < W):
					if L[s[1] + dy[i]][s[0] + dx[i]] == '.' and dp[s[1] + dy[i]][s[0] + dx[i]] == 10000000:
						d.append([s[0] + dx[i], s[1] + dy[i]])
						dp[s[1] + dy[i]][s[0] + dx[i]] = dp[s[1]][s[0]] + 1
		return dp
max_num = 0
for i in range(H):
	for j in range(W):
		dp = bfs(j, i)
		for k in dp:
			for p in k:
				if p == 10000000:
					continue
				max_num = max(max_num, p)
print(max_num)


from collections import deque
import copy
(H, W) = map(int, input().split())
S = [[x for x in input()] for _ in range(H)]
start_list = []
length = [[-1] * W for _ in range(H)]
ans = 0
for i in range(H):
	for j in range(W):
		if S[i][j] == '.':
			start_list.append((i, j))
for start in start_list:
	(h, w) = start
	d = deque([(h, w)])
	T = copy.deepcopy(S)
	L = copy.deepcopy(length)
	L[h][w] = 0
	T[h][w] = '#'
	while d:
		(h, w) = d.popleft()
		if h - 1 >= 0 and T[h - 1][w] == '.':
			d.append((h - 1, w))
			L[h - 1][w] = L[h][w] + 1
			T[h - 1][w] = '#'
			ans = max(ans, L[h - 1][w])
		if h + 1 <= H - 1 and T[h + 1][w] == '.':
			d.append((h + 1, w))
			L[h + 1][w] = L[h][w] + 1
			T[h + 1][w] = '#'
			ans = max(ans, L[h + 1][w])
		if w - 1 >= 0 and T[h][w - 1] == '.':
			d.append((h, w - 1))
			L[h][w - 1] = L[h][w] + 1
			T[h][w - 1] = '#'
			ans = max(ans, L[h][w - 1])
		if w + 1 <= W - 1 and T[h][w + 1] == '.':
			d.append((h, w + 1))
			L[h][w + 1] = L[h][w] + 1
			T[h][w + 1] = '#'
			ans = max(ans, L[h][w + 1])
print(ans)


from collections import deque
(h, w) = map(int, input().split())
maze = [list(input()) for i in range(h)]
ans = 0
for i in range(h):
	for j in range(w):
		if maze[i][j] == '.':
			visited = [[0 for k in range(w)] for l in range(h)]
			visited[i][j] = 1
			que = deque([])
			que.append((i, j, 0))
			while que:
				(x, y, cnt) = que.popleft()
				for (nx, ny) in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
					if 0 <= nx < h and 0 <= ny < w:
						if maze[nx][ny] == '.' and visited[nx][ny] == 0:
							que.append((nx, ny, cnt + 1))
							visited[nx][ny] = 1
			ans = max(ans, cnt)
print(ans)


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

def search(y, x):
	q = [(y, x)]
	vis = [[-1] * w for _ in range(h)]
	vis[y][x] = 0
	while q:
		(cy, cx) = q.pop(0)
		for (dy, dx) in ((1, 0), (-1, 0), (0, 1), (0, -1)):
			(ny, nx) = (cy + dy, cx + dx)
			if 0 <= ny < h and 0 <= nx < w and (g[ny][nx] == '.') and (vis[ny][nx] == -1):
				vis[ny][nx] = vis[cy][cx] + 1
				q.append((ny, nx))
	return max((max(l) for l in vis))
ans = 0
for i in range(h):
	for j in range(w):
		if g[i][j] == '.':
			ans = max(search(i, j), ans)
print(ans)


from collections import deque
import copy
(H, W) = list(map(int, input().split()))
maze = []
ans = 0
for i in range(H):
	maze.append(list(input()))
distancelist = []
for i in range(H):
	tmplst = [0] * W
	for j in range(W):
		if maze[i][j] == '#':
			tmplst[j] = -1
	distancelist.append(tmplst)
for x in range(H):
	for y in range(W):
		if maze[x][y] == '#':
			continue
		tmpdis = copy.deepcopy(distancelist)
		d = deque()
		start = [x, y]
		d.append(start)
		while d:
			(h, w) = d.popleft()
			now = tmpdis[h][w]
			for (i, j) in [[1, 0], [0, 1], [-1, 0], [0, -1]]:
				(dh, dw) = (h + i, w + j)
				if 0 <= dh < H and 0 <= dw < W:
					if tmpdis[dh][dw] == 0 and [dh, dw] != start:
						d.append([dh, dw])
						tmpdis[dh][dw] = now + 1
			ans = max(now, ans)
print(ans)


from collections import deque
import _pickle as cPickle
import cProfile
(h, w) = map(int, input().split())
s = [['#'] * (w + 2)] + [['#'] + list(input()) + ['#'] for i in range(h)] + [['#'] * (w + 2)]
ans = 0
A = list()
for i in range(1, h + 1):
	for j in range(1, w + 1):
		t = cPickle.loads(cPickle.dumps(s, -1))
		c = dict()
		A = list()
		if s[i][j] == '#':
			continue
		a = deque([[i, j, 0]])
		while len(a) > 0:
			(x, y, cnt) = a.popleft()
			t[x][y] = '#'
			if t[x - 1][y] == '.':
				if [x - 1, y, cnt + 1] not in A:
					a.append([x - 1, y, cnt + 1])
					A.append([x - 1, y, cnt + 1])
			if t[x + 1][y] == '.':
				if [x + 1, y, cnt + 1] not in A:
					a.append([x + 1, y, cnt + 1])
					A.append([x + 1, y, cnt + 1])
			if t[x][y - 1] == '.':
				if [x, y - 1, cnt + 1] not in A:
					a.append([x, y - 1, cnt + 1])
					A.append([x, y - 1, cnt + 1])
			if t[x][y + 1] == '.':
				if [x, y + 1, cnt + 1] not in A:
					a.append([x, y + 1, cnt + 1])
					A.append([x, y + 1, cnt + 1])
		ans = max(ans, cnt)
print(ans)


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

def bfs(h, w, sy, sx, S):
	maze = [[10 ** 9] * W for _ in range(H)]
	maze[sy - 1][sx - 1] = 0
	que = deque([[sy - 1, sx - 1]])
	count = 0
	while que:
		(y, x) = que.popleft()
		for (i, j) in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
			(nexty, nextx) = (y + i, x + j)
			if 0 <= nexty < h and 0 <= nextx < w:
				dist1 = S[nexty][nextx]
				dist2 = maze[nexty][nextx]
			else:
				continue
			if dist1 != '#':
				if dist2 > maze[y][x] + 1:
					maze[nexty][nextx] = maze[y][x] + 1
					count = max(count, maze[nexty][nextx])
					que.append([nexty, nextx])
	return count
ans = 0
for sy in range(H):
	for sx in range(W):
		if S[sy][sx] == '.':
			now = bfs(H, W, sy + 1, sx + 1, S)
			ans = max(ans, now)
print(ans)


import queue

def bfs(maze, h, w, sy, sx):
	dist = [[-1 for _ in range(w)] for _ in range(h)]
	q = queue.deque([[sy, sx]])
	dist[sy][sx] = 0
	while q:
		(y, x) = q.popleft()
		for (dy, dx) in d:
			(ny, nx) = (y + dy, x + dx)
			if 0 <= ny < h and 0 <= nx < w and (dist[ny][nx] == -1) and (maze[ny][nx] != '#'):
				dist[ny][nx] = dist[y][x] + 1
				q.append([ny, nx])
	return max([max(i) for i in dist])
(h, w) = map(int, input().split())
a = [input() for _ in range(h)]
d = [[1, 0], [0, 1], [-1, 0], [0, -1]]
ans = 0
for sy in range(h):
	for sx in range(w):
		if a[sy][sx] != '#':
			ans = max(ans, bfs(a, h, w, sy, sx))
print(ans)


from collections import deque
import numpy as np

def main():
	(H, W) = map(int, input().split())
	maze = [input() for _ in range(H)]
	ans = 0
	for x in range(H):
		for y in range(W):
			if maze[x][y] == '#':
				continue
			distance = [[0] * W for _ in range(H)]
			stack = deque([[x, y]])
			while stack:
				(h, w) = stack.popleft()
				for (i, j) in [[1, 0], [-1, 0], [0, 1], [0, -1]]:
					(new_h, new_w) = (h + i, w + j)
					if new_h < 0 or new_w < 0 or new_h >= H or (new_w >= W):
						continue
					elif maze[new_h][new_w] != '#' and distance[new_h][new_w] == 0:
						distance[new_h][new_w] = distance[h][w] + 1
						stack.append([new_h, new_w])
			distance[x][y] = 0
			ans = max(ans, np.max(distance))
	print(ans)
main()


from collections import deque
(h, w) = map(int, input().split())
S = [input() for _ in range(h)]
ans = 0
dxy = [(0, 1), (1, 0), (0, -1), (-1, 0)]
for y in range(h):
	for x in range(w):
		if S[y][x] == '#':
			continue
		q = deque([(x, y)])
		dist = [[0] * w for _ in range(h)]
		visited = [[0] * w for _ in range(h)]
		visited[y][x] = 1
		while q:
			(x, y) = q.popleft()
			for (dx, dy) in dxy:
				(nx, ny) = (x + dx, y + dy)
				if not 0 <= nx < w:
					continue
				if not 0 <= ny < h:
					continue
				if visited[ny][nx]:
					continue
				if S[ny][nx] == '#':
					continue
				visited[ny][nx] = 1
				dist[ny][nx] = dist[y][x] + 1
				q.append((nx, ny))
		ans = max(ans, max((max(row) for row in dist)))
print(ans)


from collections import deque
import copy
(h, w) = map(int, input().split())
ss = [list(input()) for i in range(h)]
ans = 0
for hh in range(h):
	for ww in range(w):
		dist = [[-1] * (w + 1) for i in range(h + 1)]
		c = copy.deepcopy(ss)
		xx = c[hh][ww]
		if xx == '#':
			continue
		dist[hh][ww] = 0
		dq = deque()
		dq.append((hh, ww))
		c[hh][ww] = '#'
		while dq:
			(y, x) = dq.popleft()
			for (dx, dy) in [[1, 0], [-1, 0], [0, 1], [0, -1]]:
				nx = x + dx
				ny = y + dy
				if 0 <= nx < w and 0 <= ny < h and (c[ny][nx] != '#'):
					dq.append((ny, nx))
					c[ny][nx] = '#'
					dist[ny][nx] = dist[y][x] + 1
		for i in dist:
			ans = max(ans, max(i))
print(ans)


from copy import deepcopy
(H, W) = map(int, input().split())
S = [list(input()) for i in range(H)]
ans = 0
queue = [[1, 0], [-1, 0], [0, 1], [0, -1]]

def now(n, s):
	t = []
	for i in queue:
		j = n[0] + i[0]
		k = n[1] + i[1]
		if 0 <= j < H and 0 <= k < W:
			if s[j][k] == '.':
				t.append([j, k])
				s[j][k] = '#'
	return [t, s]

def bfs(trust, a, s):
	t = []
	for i in trust:
		(tt, s) = now(i, s)
		t += tt
	if len(t) == 0:
		return a
	else:
		a = a + 1
		return bfs(t, a, s)
for i in range(H):
	for j in range(W):
		s = deepcopy(S)
		if S[i][j] == '.':
			s[i][j] = '#'
			ans = max(ans, bfs([[i, j]], 0, s))
print(ans)


from collections import deque
import copy
(H, W) = map(int, input().split())
S = [list(input()) for _ in range(H)]
neig = [(1, 0), (0, 1), (-1, 0), (0, -1)]
road = []
for h in range(H):
	for w in range(W):
		if S[h][w] == '.':
			road.append((h, w))
ans = 0
for (rh, rw) in road:
	(SC, q) = (copy.deepcopy(S), deque([(rh, rw, 0)]))
	SC[rh][rw] = 0
	while len(q) > 0:
		(h, w, i) = q.popleft()
		for (nh, nw) in neig:
			if 0 <= h - nh < H and 0 <= w - nw < W and (SC[h - nh][w - nw] == '.'):
				SC[h - nh][w - nw] = i + 1
				ans = max(ans, i + 1)
				q.append([h - nh, w - nw, i + 1])
print(ans)


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

def cost(x):
	v = [[0] * w for _ in range(h)]
	v[x[1]][x[0]] = 1
	que = [x]
	ans = -1
	while que:
		newque = []
		for (X, Y) in que:
			for (x, y) in ((0, -1), (-1, 0), (0, 1), (1, 0)):
				if 0 <= X + x < w and 0 <= Y + y < h and (g[Y + y][X + x] == '.') and (v[Y + y][X + x] == 0):
					v[Y + y][X + x] = 1
					newque.append((X + x, Y + y))
		ans += 1
		que = newque
	return ans
ans = 0
for i in range(w):
	for j in range(h):
		if g[j][i] == '.':
			ans = max(ans, cost((i, j)))
print(ans)


import sys
from collections import deque
(H, W) = map(int, input().split())
S = list(sys.stdin)
ans = 0
for i in range(H):
	for j in range(W):
		if S[i][j] == '#':
			continue
		dist = [[-1] * W for _ in range(H)]
		dist[i][j] = 0
		que = deque()
		que.append((i, j))
		while que:
			(i, j) = que.popleft()
			ans = max(ans, dist[i][j])
			for (ni, nj) in ((i - 1, j), (i, j + 1), (i + 1, j), (i, j - 1)):
				if 0 <= ni < H and 0 <= nj < W and (S[ni][nj] == '.') and (dist[ni][nj] == -1):
					dist[ni][nj] = dist[i][j] + 1
					que.append((ni, nj))
print(ans)


(H, W) = map(int, input().split())
s = [list(input()) for _ in range(H)]
d = [(1, 0), (0, 1), (-1, 0), (0, -1)]
ans = 0

def search(n, m):
	X = [[0] * W for _ in range(H)]
	X[n][m] = 1
	ans = -1
	que = []
	que.append((n, m))
	while que:
		newque = []
		for (x, y) in que:
			for (dx, dy) in d:
				if 0 <= x + dx < H and 0 <= y + dy < W and (s[x + dx][y + dy] == '.') and (X[x + dx][y + dy] == 0):
					X[x + dx][y + dy] = 1
					newque.append((x + dx, y + dy))
		ans += 1
		que = newque
	return ans
for i in range(H):
	for j in range(W):
		if s[i][j] == '.':
			ans = max(ans, search(i, j))
print(ans)


(n, m) = map(int, input().split())
l = ['#' + input() + '#' for an in range(n)]
l = ['#' * (m + 2)] + l + ['#' * (m + 2)]
inf = 10 ** 7
from queue import Queue as qu
mo = [(1, 0), (-1, 0), (0, 1), (0, -1)]
ret = 0
for i in range(1, n + 1):
	for j in range(1, m + 1):
		if l[i][j] == '.':
			q = qu()
			step = [[inf for c in range(m + 2)] for x in range(n + 2)]
			step[i][j] = 0
			q.put((i, j))
			while not q.empty():
				d = q.get()
				for g in mo:
					(c, cc) = (g[0] + d[0], g[1] + d[1])
					if step[c][cc] == inf and l[c][cc] == '.':
						q.put((c, cc))
						step[c][cc] = step[d[0]][d[1]] + 1
						ret = max(ret, step[c][cc])
print(ret)


(h, w) = map(int, input().split())
s = [input() for _ in range(h)]
ans = 0
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
import queue
for si in range(h):
	for sj in range(w):
		if s[si][sj] == '#':
			continue
		dist = [[-1 for a in range(w)] for b in range(h)]
		q = queue.Queue()
		q.put([si, sj])
		dist[si][sj] = 0
		while not q.empty():
			(nowi, nowj) = q.get()
			for ne in range(4):
				(nexti, nextj) = (nowi + dx[ne], nowj + dy[ne])
				if nexti < 0 or nexti >= h or nextj < 0 or (nextj >= w):
					continue
				if dist[nexti][nextj] != -1 or s[nexti][nextj] == '#':
					continue
				dist[nexti][nextj] = dist[nowi][nowj] + 1
				q.put([nexti, nextj])
				ans = max(ans, dist[nexti][nextj])
print(ans)


from collections import deque
(H, W) = map(int, input().split())
S = [''] * H
for i in range(H):
	S[i] = input()
dests = ((-1, 0), (0, -1), (1, 0), (0, 1))

def maze(sx, sy):
	d = deque()
	dist = [[-1] * W for i in range(H)]
	dist[sx][sy] = 0
	d.append((sx, sy))
	while True:
		(x, y) = d.popleft()
		for dest in dests:
			(nx, ny) = (x + dest[0], y + dest[1])
			if nx >= 0 and nx < H and (ny >= 0) and (ny < W) and (S[nx][ny] == '.') and (dist[nx][ny] == -1):
				d.append((nx, ny))
				dist[nx][ny] = dist[x][y] + 1
		if not d:
			return dist[x][y]
ans = 0
for i in range(H):
	for j in range(W):
		if S[i][j] == '#':
			continue
		ans = max(ans, maze(i, j))
print(ans)


import copy
(H, W) = map(int, input().split())
maze = []
maze.append(['#'] * (W + 2))
for i in range(H):
	line = input()
	line_n = ['#'] + [line[i] for i in range(W)] + ['#']
	maze.append(line_n)
maze.append(['#'] * (W + 2))
for i in range(H + 2):
	for j in range(W + 2):
		if maze[i][j] == '#':
			maze[i][j] = 9
maze_copy = copy.deepcopy(maze)
global_max = 0
for i in range(1, H + 1):
	for j in range(1, W + 1):
		maze = copy.deepcopy(maze_copy)
		sx = i
		sy = j
		if maze[i][j] != 9:
			pos = [[sx, sy, 0]]
			max_depth = 0
			while len(pos) > 0:
				(x, y, depth) = pos.pop(0)
				if depth > max_depth:
					max_depth = depth
				maze[x][y] = 0
				if maze[x - 1][y] == '.':
					pos.append([x - 1, y, depth + 1])
					maze[x - 1][y] = 0
				if maze[x][y - 1] == '.':
					pos.append([x, y - 1, depth + 1])
					maze[x][y - 1] = 0
				if maze[x + 1][y] == '.':
					pos.append([x + 1, y, depth + 1])
					maze[x + 1][y] = 0
				if maze[x][y + 1] == '.':
					pos.append([x, y + 1, depth + 1])
					maze[x][y + 1] = 0
			if max_depth > global_max:
				global_max = max_depth
print(global_max)


from collections import deque
from copy import deepcopy
(h, w) = map(int, input().split())
a = [list(input()) for _ in range(h)]
r = 0
for i in range(h):
	for j in range(w):
		if a[i][j] == '.':
			b = deepcopy(a)
			q = deque()
			b[i][j] = 0
			q.append((i, j))
			while q:
				(i, j) = q.popleft()
				r = max(r, b[i][j])
				for di in range(-1, 2):
					i1 = i + di
					if 0 <= i1 < h:
						for dj in range(di % 2 - 1, 2, 2):
							j1 = j + dj
							if 0 <= j1 < w and b[i1][j1] == '.':
								b[i1][j1] = b[i][j] + 1
								q.append((i1, j1))
print(r)


from collections import deque
(H, W) = map(int, input().split())
S = list()
for i in range(H):
	S.append(list(input()))
mx = 0
for i in range(H):
	for j in range(W):
		if S[i][j] == '#':
			continue
		q = deque([(i, j, 0)])
		T = [[S[k][l] for l in range(W)] for k in range(H)]
		T[i][j] = '#'
		while q:
			(x, y, c) = q.popleft()
			for (dx, dy) in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
				(nx, ny) = (x + dx, y + dy)
				if 0 <= nx < H and 0 <= ny < W and (T[nx][ny] == '.'):
					T[nx][ny] = '#'
					q.append((nx, ny, c + 1))
		mx = max(mx, c)
print(mx)


from copy import deepcopy
from collections import deque
(h, w) = map(int, input().split())
s = [['#'] * (w + 2)] + [['#'] + list(input()) + ['#'] for i in range(h)] + [['#'] * (w + 2)]
ans = 0
for i in range(1, h + 1):
	for j in range(1, w + 1):
		t = deepcopy(s)
		if s[i][j] == '#':
			continue
		a = deque([[i, j, 0]])
		while len(a) > 0:
			(x, y, cnt) = a.popleft()
			t[x][y] = '#'
			if t[x - 1][y] == '.':
				a.append([x - 1, y, cnt + 1])
				t[x - 1][y] = '#'
			if t[x + 1][y] == '.':
				a.append([x + 1, y, cnt + 1])
				t[x + 1][y] = '#'
			if t[x][y - 1] == '.':
				a.append([x, y - 1, cnt + 1])
				t[x][y - 1] = '#'
			if t[x][y + 1] == '.':
				a.append([x, y + 1, cnt + 1])
				t[x][y + 1] = '#'
		ans = max(ans, cnt)
print(ans)


import queue
(h, w) = map(int, input().split())
s = []
for _ in range(h):
	s.append(input())
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '.':
			seen = [[0 for _ in range(w)] for _ in range(h)]
			length = [[0 for _ in range(w)] for _ in range(h)]
			q = queue.Queue()
			q.put([i, j])
			seen[i][j] = 1
			while not q.empty():
				(ci, cj) = q.get()
				for (ni, nj) in [[ci - 1, cj], [ci + 1, cj], [ci, cj - 1], [ci, cj + 1]]:
					if 0 <= ni < h and 0 <= nj < w and (s[ni][nj] == '.') and (seen[ni][nj] == 0):
						q.put([ni, nj])
						length[ni][nj] = length[ci][cj] + 1
						seen[ni][nj] = 1
			ans = max(ans, length[ci][cj])
print(ans)


from collections import deque
(h, w) = map(int, input().split())
l = list()
l.append('#' * (w + 2))
for i in range(h):
	l.append('#' + input() + '#')
l.append('#' * (w + 2))
p = 0
for i in range(1, h + 1):
	for j in range(1, w + 1):
		if l[i][j] == '#':
			continue
		s = [[-1 for a in b] for b in l]
		q = deque([[i, j]])
		s[i][j] = 0
		while len(q) > 0:
			(a, b) = q.popleft()
			for (x, y) in [[1, 0], [0, 1], [-1, 0], [0, -1]]:
				if l[a + x][b + y] == '#' or s[a + x][b + y] > -1:
					continue
				q.append([a + x, b + y])
				s[a + x][b + y] = s[a][b] + 1
		r = 0
		for x in s:
			for y in x:
				r = max(y, r)
		p = max(r, p)
print(p)


import copy, collections, itertools
(H, W) = [int(_) for _ in input().split()]
S_ = [['#'] * (W + 2)] + [['#'] + list(input()) + ['#'] for _ in range(H)] + [['#'] * (W + 2)]
ans = 0
for (i, j) in itertools.product(range(1, H + 1), range(1, W + 1)):
	if S_[i][j] == '.':
		S = copy.deepcopy(S_)
		S[i][j] = '#'
		q = collections.deque([(i, j, 0)])
		while q:
			(x, y, d) = q.popleft()
			for (dx, dy) in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
				if S[x + dx][y + dy] == '.':
					(X, Y) = (x + dx, y + dy)
					S[X][Y] = '#'
					q += [(X, Y, d + 1)]
		ans = max(d, ans)
print(ans)


from collections import deque
(H, W) = map(int, input().split())
Maze = [list(input()) for _ in range(H)]
ans = 0
sy = 0
while sy < H:
	sx = 0
	while sx < W:
		if Maze[sy][sx] == '.':
			M_cnt = 0
			q = deque()
			memo = [[-1] * W for _ in range(H)]
			memo[sy][sx] = 0
			q.append([sy, sx])
			while q:
				(cy, cx) = q.popleft()
				for (ny, nx) in zip((cy, cy, cy + 1, cy - 1), (cx + 1, cx - 1, cx, cx)):
					if ny >= 0 and ny < H and (nx >= 0) and (nx < W) and (Maze[ny][nx] == '.') and (memo[ny][nx] < 0):
						q.append([ny, nx])
						memo[ny][nx] = memo[cy][cx] + 1
			ans = max(ans, max([max(m) for m in memo]))
		sx += 1
	sy += 1
print(ans)


from collections import deque
(h, w) = list(map(int, input().split()))
maze = [input() for _ in range(h)]
ans = 0

def bfs(sx, sy):
	dx = (1, 0, -1, 0)
	dy = (0, 1, 0, -1)
	d = [[-1] * w for _ in range(h)]
	q = deque([])
	q.append((sx, sy))
	d[sx][sy] = 0
	ans = 0
	while q:
		(x, y) = q.popleft()
		for i in range(4):
			nx = x + dx[i]
			ny = y + dy[i]
			if 0 <= nx < h and 0 <= ny < w and (maze[nx][ny] != '#') and (d[nx][ny] == -1):
				q.append((nx, ny))
				d[nx][ny] = d[x][y] + 1
				ans = max(ans, d[nx][ny])
	return ans
for i in range(h):
	for j in range(w):
		if maze[i][j] == '.':
			ans = max(ans, bfs(i, j))
print(ans)


(H, W) = map(int, input().split())
maze = [list(input()) for j in range(H)]

def bfs(h, w):
	checked = [[False for i in range(W)] for j in range(H)]
	q = [(h, w, 0)] if maze[h][w] == '.' else []
	checked[h][w] = True
	g_n = 0
	while q:
		(h_, w_, n) = q.pop(0)
		g_n = max(n, g_n)
		for (i, j) in zip([0, 0, -1, 1], [-1, 1, 0, 0]):
			if 0 <= h_ + i < H and 0 <= w_ + j < W:
				if checked[h_ + i][w_ + j]:
					continue
				checked[h_ + i][w_ + j] = True
				if maze[h_ + i][w_ + j] == '.':
					q.append((h_ + i, w_ + j, n + 1))
	return g_n
n = 0
for i in range(H):
	for j in range(W):
		n = max(n, bfs(i, j))
print(n)


import queue
(h, w) = map(int, input().split())
s = '#' * (w + 2)
for _ in range(h):
	s += '#' + input() + '#'
s += '#' * (w + 2)
ans = 0
for i in range((w + 2) * (h + 2)):
	if s[i] == '#':
		continue
	dist = [10 ** 5] * (w + 2) * (h + 2)
	dist[i] = 0
	q = queue.Queue()
	q.put(i)
	while not q.empty():
		x = q.get()
		for j in (1, -1, w + 2, -w - 2):
			if s[j + x] == '#':
				continue
			if dist[j + x] > dist[x] + 1:
				dist[j + x] = dist[x] + 1
				q.put(j + x)
	for k in range((w + 2) * (h + 2)):
		if dist[k] != 10 ** 5:
			ans = max(ans, dist[k])
print(ans)


from collections import deque
import numpy as np
(H, W) = map(int, input().split())
maze = [input() for _ in range(H)]
dxy = [[1, 0], [0, 1], [-1, 0], [0, -1]]
ans = 0
for x in range(H):
	for y in range(W):
		if maze[x][y] == '#':
			continue
		seen = [[0] * W for _ in range(H)]
		que = deque([[x, y]])
		while que:
			(vx, vy) = que.popleft()
			for (i, j) in dxy:
				(next_x, next_y) = (vx + i, vy + j)
				if not 0 <= next_x < H or not 0 <= next_y < W:
					continue
				elif maze[next_x][next_y] != '#' and seen[next_x][next_y] == 0:
					seen[next_x][next_y] = seen[vx][vy] + 1
					que.append([next_x, next_y])
		seen[x][y] = 0
		ans = max(ans, np.max(seen))
print(ans)


import queue

def bfs(sx, sy):
	dist = [[-1 for _ in range(w)] for __ in range(h)]
	dist[sx][sy] = 0
	q = queue.Queue()
	q.put([sx, sy])
	res = 0
	while not q.empty():
		(vx, vy) = q.get()
		for (dx, dy) in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
			x = vx + dx
			y = vy + dy
			if 0 <= x < h and 0 <= y < w and (S[x][y] == '.') and (dist[x][y] == -1):
				q.put([x, y])
				dist[x][y] = dist[vx][vy] + 1
				res = max(res, dist[x][y])
	return res
(h, w) = map(int, input().split())
S = [list(input()) for _ in range(h)]
ans = 0
for i in range(h):
	for j in range(w):
		if S[i][j] == '.':
			ans = max(ans, bfs(i, j))
print(ans)


from queue import Queue
(H, W) = map(int, input().split())
S = [input() for _ in range(H)]
ans = 0
for h in range(H):
	for w in range(W):
		if S[h][w] != '.':
			continue
		q = Queue()
		seen = [[False] * W for _ in range(H)]
		q.put((h, w, 0))
		seen[h][w] = True
		while not q.empty():
			(h, w, d) = q.get()
			for (nh, nw) in [(h + 1, w), (h, w + 1), (h - 1, w), (h, w - 1)]:
				if nh < 0 or nw < 0 or nh >= H or (nw >= W):
					continue
				if not seen[nh][nw] and S[nh][nw] == '.':
					q.put((nh, nw, d + 1))
					seen[nh][nw] = True
					ans = max(d + 1, ans)
print(ans)


from collections import deque
d = [(-1, 0), (1, 0), (0, 1), (0, -1)]

def bfs(y, x, c):
	q = deque()
	q.append((y, x, c))
	ma = 0
	visit[y][x] = 1
	while q:
		(y, x, c) = q.popleft()
		ma = max(ma, c)
		for (dy, dx) in d:
			if 0 <= y + dy < h and 0 <= x + dx < w:
				if area[y + dy][x + dx] == '.' and visit[y + dy][x + dx] == 0:
					q.append((y + dy, x + dx, c + 1))
					visit[y + dy][x + dx] = 1
	return ma
(h, w) = map(int, input().split())
area = []
for i in range(h):
	area.append(list(input()))
ans = 0
for i in range(h):
	for j in range(w):
		if area[i][j] == '.':
			visit = [[0] * w for i in range(h)]
			ans = max(ans, bfs(i, j, 0))
print(ans)


from collections import deque
(H, W) = map(int, input().split())
S = [input() for _ in range(H)]
ans = 0
d = deque([])
for i in range(H):
	for j in range(W):
		if S[i][j] == '#':
			continue
		d.append((i, j, 0))
		visited = [[-1] * W for _ in range(H)]
		visited[i][j] = 0
		while d:
			(x, y, c) = d.popleft()
			for (dx, dy) in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
				(nx, ny) = (x + dx, y + dy)
				if 0 <= nx < H and 0 <= ny < W and (visited[nx][ny] == -1) and (S[nx][ny] == '.'):
					visited[nx][ny] = c + 1
					d.append((nx, ny, c + 1))
		ans = max(ans, c)
print(ans)


(h, w) = map(int, input().split())
C = [list(input()) for i in range(h)]
startls = []
for i in range(h):
	for j in range(w):
		if C[i][j] == '.':
			startls.append([i, j])
dy_dx = [[1, 0], [0, 1], [-1, 0], [0, -1]]
ans = 0
for start in startls:
	visited = [[-1 for i in range(w)] for i in range(h)]
	visited[start[0]][start[1]] = 0
	cost = 0
	queue = [start]
	while len(queue) > 0:
		now = queue.pop(0)
		cost = visited[now[0]][now[1]] + 1
		for i in range(4):
			y = now[0] + dy_dx[i][0]
			x = now[1] + dy_dx[i][1]
			if 0 <= y < h and 0 <= x < w:
				if C[y][x] != '#' and visited[y][x] == -1:
					visited[y][x] = cost
					queue.append([y, x])
					ans = max(ans, cost)
print(ans)


from collections import deque
(H, W) = map(int, input().split())
X = [1] * (W + 2)
for _ in range(H):
	X += [1] + [1 if a == '#' else 0 for a in input()] + [1]
X += [1] * (W + 2)
(H, W) = (H + 2, W + 2)

def BFS(i0=0):
	Q = deque([i0])
	D = [-1] * (H * W)
	D[i0] = 0
	while Q:
		x = Q.popleft()
		for y in (x + W, x - W, x + 1, x - 1):
			if X[y] == 0:
				if D[y] == -1:
					D[y] = D[x] + 1
					Q.append(y)
	return D
ma = 0
for i in range(H):
	for j in range(W):
		if X[i * W + j] == 0:
			ma = max(ma, max(BFS(i * W + j)))
print(ma)


from collections import deque
(H, W) = list(map(int, input().split()))
S = [input() for _ in range(H)]
start = [[j, i] for i in range(W) for j in range(H)]
res = 0
for pt in start:
	v = [[0] * W for _ in range(H)]
	if S[pt[0]][pt[1]] == '#':
		continue
	q = deque([pt + [0]])
	dist = 0
	while len(q) > 0:
		(h, w, cnt) = q.popleft()
		if v[h][w] == 1:
			continue
		else:
			v[h][w] = 1
		dist = max(dist, cnt)
		for (dh, dw) in [[1, 0], [-1, 0], [0, 1], [0, -1]]:
			nh = h + dh
			nw = w + dw
			if 0 > nh or nh >= H or 0 > nw or (nw >= W) or (S[nh][nw] == '#'):
				continue
			q.append([nh, nw, cnt + 1])
	res = max(res, dist)
print(res)


from itertools import count, combinations, product
(H, W) = map(int, input().split())
H += 2
W += 2
visited = [2 ** 31] * (W * H)
for i in range(1, H - 1):
	S = input()
	for (j, v) in zip(range(1, W - 1), S):
		if v == '.':
			visited[i * W + j] = 0
res = 1
D = (W, -W, 1, -1)
for i in range(W * H):
	if visited[i] == 2 ** 31:
		continue
	q = [i]
	visited[i] = i
	for dist in count():
		if not q:
			break
		nq = []
		for j in q:
			for d in D:
				if visited[j + d] < i:
					visited[j + d] = i
					nq.append(j + d)
		q = nq
	res = max(dist, res)
print(res - 1)


import sys
from io import StringIO
import unittest
import copy
from collections import deque

def yn(b):
	print('Yes' if b == 1 else 'No')
	return

def sagasu(h, w, mp, sh, sw):
	d = deque()
	x = sw
	y = sh
	d.append([y, x, 0])
	while len(d) > 0:
		(y, x, cnt) = d.popleft()
		if mp[y][x] == -2 or mp[y][x] > cnt:
			mp[y][x] = cnt
			nxt = [[y - 1, x], [y + 1, x], [y, x - 1], [y, x + 1]]
			for nx in nxt:
				y2 = nx[0]
				x2 = nx[1]
				if y2 < 0:
					continue
				if y2 >= h:
					continue
				if x2 < 0:
					continue
				if x2 >= w:
					continue
				if mp[y2][x2] == -2 or mp[y2][x2] > cnt:
					d.append([y2, x2, cnt + 1])
	ret = -1
	for y in range(h):
		for x in range(w):
			ret = max(ret, mp[y][x])
	return ret

def resolve():
	readline = sys.stdin.readline
	(h, w) = list(map(int, readline().rstrip().split()))
	mp = [[0 for i in range(w)] for j in range(h)]
	for y in range(h):
		ss = readline().rstrip()
		for x in range(w):
			if ss[x] == '#':
				mp[y][x] = -1
			else:
				mp[y][x] = -2
	ans = 0
	for y in range(h):
		for x in range(w):
			if mp[y][x] == -2:
				mp2 = copy.deepcopy(mp)
				n = sagasu(h, w, mp2, y, x)
				ans = max(ans, n)
	print(ans)
	return
if 'doTest' not in globals():
	resolve()
	return


from collections import deque
(H, W) = map(int, input().split())
S = [list(input()) for _ in range(H)]
ans = 0

def bfs(y, x, m):
	g = [[None if S[i][j] == '.' else -1 for j in range(W)] for i in range(H)]
	g[y][x] = 0
	q = deque()
	q.append((y, x))
	while q:
		(i, j) = q.popleft()
		for (di, dj) in ((0, 1), (1, 0), (-1, 0), (0, -1)):
			ni = i + di
			nj = j + dj
			if 0 <= ni < H and 0 <= nj < W and (g[ni][nj] is None):
				g[ni][nj] = g[i][j] + 1
				q.append((ni, nj))
	return max((max(r) for r in g))
for i in range(H):
	for j in range(W):
		if S[i][j] == '.':
			deq = bfs(i, j, S)
			if ans < deq:
				ans = deq
print(ans)


from collections import deque
(h, w) = map(int, input().split())
s = [input() for _ in range(h)]
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '#':
			continue
		q = deque([(i, j)])
		dist = [[-1] * w for _ in range(h)]
		dist[i][j] = 0
		while q:
			(x, y) = q.popleft()
			for (k, l) in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
				if 0 <= x + k < h and 0 <= y + l < w and (dist[x + k][y + l] < 0) and (s[x + k][y + l] == '.'):
					dist[x + k][y + l] = dist[x][y] + 1
					ans = max(ans, dist[x + k][y + l])
					q.append((x + k, y + l))
print(ans)


from collections import deque
(H, W) = map(int, input().split())
maze = [list(input()) for _ in range(H)]
directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
ans = 0
for sh in range(H):
	for sw in range(W):
		if maze[sh][sw] == '#':
			continue
		dist = [[-1] * W for _ in range(H)]
		dist[sh][sw] = 0
		que = deque([[sh, sw]])
		while que:
			(nh, nw) = que.pop()
			for (dh, dw) in directions:
				(tmp_h, tmp_w) = (nh + dh, nw + dw)
				if not (0 <= tmp_h < H and 0 <= tmp_w < W):
					continue
				if maze[tmp_h][tmp_w] == '#':
					continue
				if dist[tmp_h][tmp_w] != -1:
					continue
				dist[tmp_h][tmp_w] = dist[nh][nw] + 1
				que.appendleft([tmp_h, tmp_w])
		ans = max(ans, max([max(d) for d in dist]))
print(ans)


(H, W) = map(int, input().split())
grid = [None] * H
for i in range(H):
	grid[i] = input()
ans = 0
from collections import deque
for i in range(H):
	for j in range(W):
		q = deque()
		q.append([i, j, 0])
		seen = [[False for j in range(W)] for i in range(H)]
		while q:
			node = q.popleft()
			y = node[0]
			x = node[1]
			dist = node[2]
			if grid[y][x] == '#':
				continue
			if seen[y][x]:
				continue
			seen[y][x] = True
			if dist > ans:
				ans = dist
			cases = ((0, 1), (0, -1), (1, 0), (-1, 0))
			for c in cases:
				if 0 <= y + c[0] < H and 0 <= x + c[1] < W:
					q.append([y + c[0], x + c[1], dist + 1])
print(ans)


(h, w) = map(int, input().split())
g = [[*input()] for _ in range(h)]
from collections import *
a = 0
for sx in range(h):
	for sy in range(w):
		if g[sx][sy] == '#':
			continue
		d = [[-1] * w for _ in range(h)]
		d[sx][sy] = 0
		q = deque([(sx, sy)])
		while q:
			(x, y) = q.popleft()
			t = d[x][y] + 1
			for (dx, dy) in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
				(nx, ny) = (x + dx, y + dy)
				if 0 <= nx < h and 0 <= ny < w and (g[nx][ny] == '.') and (d[nx][ny] < 0):
					d[nx][ny] = t
					q.append((nx, ny))
					a = max(a, t)
print(a)


from collections import deque
(h, w) = map(int, input().split())
S = [input() for _ in range(h)]
inf = float('inf')
ans = 0
for i in range(h):
	for j in range(w):
		if S[i][j] == '#':
			continue
		else:
			D = [[inf for _ in range(w)] for _ in range(h)]
			D[i][j] = 0
			que = deque([(i, j)])
			while que:
				(si, sj) = que.popleft()
				for (ni, nj) in [(si + 1, sj), (si - 1, sj), (si, sj + 1), (si, sj - 1)]:
					if 0 <= ni < h and 0 <= nj < w and (S[ni][nj] != '#'):
						if D[ni][nj] > D[si][sj] + 1:
							D[ni][nj] = D[si][sj] + 1
							que.append((ni, nj))
							ans = max(ans, D[si][sj] + 1)
print(ans)


import math
from math import gcd, pi, sqrt
INF = float('inf')
MOD = 10 ** 9 + 7
import sys
sys.setrecursionlimit(10 ** 6)
import itertools
import bisect
from collections import Counter, deque

def i_input():
	return int(input())

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

def i_list():
	return list(i_map())

def i_row(N):
	return [i_input() for _ in range(N)]

def i_row_list(N):
	return [i_list() for _ in range(N)]

def s_input():
	return input()

def s_map():
	return input().split()

def s_list():
	return list(s_map())

def s_row(N):
	return [s_input for _ in range(N)]

def s_row_str(N):
	return [s_list() for _ in range(N)]

def s_row_list(N):
	return [list(s_input()) for _ in range(N)]

def main():
	(H, W) = i_map()
	S = [input() for i in range(H)]
	dy_dx = [[1, 0], [0, 1], [-1, 0], [0, -1]]
	ans = 0
	for sy in range(H):
		for sx in range(W):
			if S[sy][sx] == '#':
				continue
			dist = [[-1 for _ in range(W)] for _ in range(H)]
			dist[sy][sx] = 0
			d = deque()
			d.append([sx, sy])
			while d:
				(nx, ny) = d.popleft()
				for (dy, dx) in dy_dx:
					(y, x) = (ny + dy, nx + dx)
					if 0 <= y < H and 0 <= x < W and (S[y][x] != '#') and (dist[y][x] == -1):
						dist[y][x] = dist[ny][nx] + 1
						d.append([x, y])
			ans = max(ans, max(list(itertools.chain.from_iterable(dist))))
	print(ans)

def __starting_point():
	main()
__starting_point()


import math
import sys
sys.setrecursionlimit(10000)
(H, W) = map(int, input().split())
S = []
for i in range(H):
	S.append(str(input()))

def main(l, d, cnt):
	tmp = []
	for n in l:
		(i, j) = (n[0], n[1])
		if 0 < i and S[i - 1][j] == '.':
			if d[i - 1][j] > d[i][j] + 1:
				d[i - 1][j] = d[i][j] + 1
				tmp.append([i - 1, j])
		if i < H - 1 and S[i + 1][j] == '.':
			if d[i + 1][j] > d[i][j] + 1:
				d[i + 1][j] = d[i][j] + 1
				tmp.append([i + 1, j])
		if 0 < j and S[i][j - 1] == '.':
			if d[i][j - 1] > d[i][j] + 1:
				d[i][j - 1] = d[i][j] + 1
				tmp.append([i, j - 1])
		if j < W - 1 and S[i][j + 1] == '.':
			if d[i][j + 1] > d[i][j] + 1:
				d[i][j + 1] = d[i][j] + 1
				tmp.append([i, j + 1])
	if tmp == []:
		return cnt
	else:
		cnt += 1
		return main(tmp, d, cnt)
ans = 0
for i in range(H):
	for j in range(W):
		if S[i][j] == '.':
			d = [[float('inf') for i in range(W)] for j in range(H)]
			d[i][j] = 0
			cnt = main([[i, j]], d, 0)
			ans = max(ans, cnt)
print(ans)


from collections import deque
(h, w) = list(map(int, input().split()))
s = [list(input()) for _ in range(h)]
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '.':
			cnt = [[-1] * w for _ in range(h)]
			cnt[i][j] = 0
			queue = deque()
			queue.append([i, j])
			for k in range(100 * h * w):
				if len(queue) == 0:
					break
				num = queue.popleft()
				num1 = num[0]
				num2 = num[1]
				if num1 != 0:
					if s[num1 - 1][num2] == '.' and cnt[num1 - 1][num2] == -1:
						cnt[num1 - 1][num2] = cnt[num1][num2] + 1
						queue.append([num1 - 1, num2])
				if num2 != 0:
					if s[num1][num2 - 1] == '.' and cnt[num1][num2 - 1] == -1:
						cnt[num1][num2 - 1] = cnt[num1][num2] + 1
						queue.append([num1, num2 - 1])
				if num1 != h - 1:
					if s[num1 + 1][num2] == '.' and cnt[num1 + 1][num2] == -1:
						cnt[num1 + 1][num2] = cnt[num1][num2] + 1
						queue.append([num1 + 1, num2])
				if num2 != w - 1:
					if s[num1][num2 + 1] == '.' and cnt[num1][num2 + 1] == -1:
						cnt[num1][num2 + 1] = cnt[num1][num2] + 1
						queue.append([num1, num2 + 1])
			cnt2 = 0
			for k in range(h):
				cnt2 = max(cnt2, max(cnt[k]))
			ans = max(ans, cnt2)
print(ans)


from collections import deque
(H, W) = map(int, input().split())
S = []
for _ in range(H):
	S.append(input())
yudlr = [-1, 1, 0, 0]
xudlr = [0, 0, -1, 1]
D = 0
for i in range(H):
	for j in range(W):
		if S[i][j] == '#':
			continue
		d = [[-1] * W for _ in range(H)]
		d[i][j] = 0
		Q = deque()
		Q.append([i, j])
		while len(Q) > 0:
			q = Q.popleft()
			(y, x) = (q[0], q[1])
			for k in range(4):
				y1 = y + yudlr[k]
				x1 = x + xudlr[k]
				if y1 < 0 or y1 >= H or x1 < 0 or (x1 >= W):
					continue
				if S[y1][x1] == '#':
					continue
				if d[y1][x1] != -1:
					continue
				d[y1][x1] = d[y][x] + 1
				Q.append([y1, x1])
		Dij = max(list(map(lambda x: max(x), d)))
		D = max(D, Dij)
print(D)


from collections import deque
MAX_H = 20
MAX_W = 20
(H, W) = [int(x) for x in input().split()]
S = [input() for _ in range(H)]

def valid(i, j, B):
	return 0 <= i < H and 0 <= j < W and (S[i][j] == '.') and (not B[i][j])

def bfs(i, j):
	B = [[False] * W for _ in range(H)]
	dist = 0
	q = deque([[i, j, -1]])
	while len(q) > 0:
		p = q.popleft()
		i = p[0]
		j = p[1]
		if B[i][j]:
			continue
		d = p[2] + 1
		dist = max(dist, d)
		B[i][j] = True
		if valid(i - 1, j, B):
			q.append([i - 1, j, d])
		if valid(i + 1, j, B):
			q.append([i + 1, j, d])
		if valid(i, j - 1, B):
			q.append([i, j - 1, d])
		if valid(i, j + 1, B):
			q.append([i, j + 1, d])
	return dist
ans = 0
for i in range(H):
	for j in range(W):
		if S[i][j] == '.':
			ans = max(ans, bfs(i, j))
print(ans)


from collections import deque

def getdistance(row, col, sw, h, w):
	maze = deque([[row, col, 0]])
	marker = [[0] * w for _ in range(h)]
	marker[row][col] = 1
	while len(maze) != 0:
		(r, c, d) = maze.popleft()
		if r != 0:
			if sw[r - 1][c] != '#' and marker[r - 1][c] != 1:
				marker[r - 1][c] = 1
				maze.append([r - 1, c, d + 1])
		if r != h - 1:
			if sw[r + 1][c] != '#' and marker[r + 1][c] != 1:
				marker[r + 1][c] = 1
				maze.append([r + 1, c, d + 1])
		if c != w - 1:
			if sw[r][c + 1] != '#' and marker[r][c + 1] != 1:
				marker[r][c + 1] = 1
				maze.append([r, c + 1, d + 1])
		if c != 0:
			if sw[r][c - 1] != '#' and marker[r][c - 1] != 1:
				marker[r][c - 1] = 1
				maze.append([r, c - 1, d + 1])
	return d
(h, w) = map(int, input().split())
sw = [input() for _ in range(h)]
ans = 0
for row in range(h):
	for col in range(w):
		if sw[row][col] == '#':
			continue
		ans = max(ans, getdistance(row, col, sw, h, w))
print(ans)


from collections import deque
dxdy = [(1, 0), (-1, 0), (0, 1), (0, -1)]
(h, w) = map(int, input().split())
s = [input() for _ in range(h)]
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '#':
			continue
		d = [[-1] * w for _ in range(h)]
		q = deque([(i, j)])
		d[i][j] = 0
		while q:
			(y, x) = q.popleft()
			for (dx, dy) in dxdy:
				if 0 <= x + dx < w and 0 <= y + dy < h and (s[y + dy][x + dx] == '.') and (d[y + dy][x + dx] == -1):
					q.append((y + dy, x + dx))
					d[y + dy][x + dx] = d[y][x] + 1
		for row in d:
			ans = max(ans, max(row))
print(ans)


from collections import deque

def main():
	(row, col) = list(map(int, input().split()))
	S = [list(input()) for _ in range(row)]
	ans = 0
	for r in range(row):
		for c in range(col):
			if S[r][c] == '#':
				continue
			q = deque()
			q.append((r, c))
			dist = [[-1 for _ in range(col)] for _ in range(row)]
			dist[r][c] = 0
			while q:
				(r, c) = q.popleft()
				for (dr, dc) in ((-1, 0), (1, 0), (0, -1), (0, 1)):
					(nr, nc) = (r + dr, c + dc)
					if not (0 <= nr < row and 0 <= nc < col):
						continue
					if S[nr][nc] == '#':
						continue
					if dist[nr][nc] != -1:
						continue
					q.append((nr, nc))
					dist[nr][nc] = dist[r][c] + 1
					ans = max(ans, dist[nr][nc])
	print(ans)

def __starting_point():
	main()
__starting_point()


(h, w) = map(int, input().split())
l = []
for i in range(h):
	s = [x for x in input()]
	l.append(s)
move = [[1, 0], [-1, 0], [0, 1], [0, -1]]

def bfs(x, y):
	done = [[-1 for i in range(w)] for j in range(h)]
	(ans, cnt) = (0, 0)
	que = [[x, y, cnt]]
	done[y][x] = 0
	while que:
		(nx, ny, cnt) = que.pop(0)
		for (dx, dy) in move:
			mx = nx + dx
			my = ny + dy
			if 0 <= mx < w and 0 <= my < h and (done[my][mx] == -1) and (l[my][mx] == '.'):
				done[my][mx] = cnt + 1
				que.append([mx, my, cnt + 1])
				ans = max(ans, cnt + 1)
	return ans
ans_r = 0
for i in range(w):
	for j in range(h):
		if l[j][i] == '.':
			now = bfs(i, j)
			ans_r = max(now, ans_r)
print(ans_r)


(h, w) = map(int, input().split())
import sys
import queue
mok = queue.Queue()
s = [[str(c) for c in l.strip()] for l in sys.stdin]
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
maxx = 0
for i in range(h):
	for j in range(w):
		d = [[-1] * w for k in range(h)]
		d[i][j] = 0
		if s[i][j] == '.':
			mok.put([i, j])
			while not mok.empty():
				[nx, ny] = mok.get()
				for k in range(4):
					if 0 <= nx + dx[k] < h and 0 <= ny + dy[k] < w and (s[nx + dx[k]][ny + dy[k]] == '.') and (d[nx + dx[k]][ny + dy[k]] == -1):
						d[nx + dx[k]][ny + dy[k]] = d[nx][ny] + 1
						if d[nx + dx[k]][ny + dy[k]] > maxx:
							maxx = d[nx + dx[k]][ny + dy[k]]
						mok.put([nx + dx[k], ny + dy[k]])
print(maxx)


(H, W) = map(int, input().split())
grid = [None] * H
for i in range(H):
	grid[i] = input()
from collections import deque
ans = 0
INF = 10 ** 9
ans = 0
for i in range(H):
	for j in range(W):
		dist = [[INF for j in range(W)] for i in range(H)]
		q = deque()
		q.append([i, j, 0])
		while q:
			node = q.popleft()
			y = node[0]
			x = node[1]
			d = node[2]
			if grid[y][x] == '#':
				continue
			if dist[y][x] <= d:
				continue
			if ans < d:
				ans = d
			dist[y][x] = d
			cases = ((0, 1), (0, -1), (1, 0), (-1, 0))
			for c in cases:
				if 0 <= y + c[0] < H and 0 <= x + c[1] < W:
					q.append([y + c[0], x + c[1], d + 1])
print(ans)


from collections import deque
(h, w) = map(int, input().split())
s = [input() for i in range(h)]

def bfs(i0, j0):
	INF = 100
	search = deque([(i0, j0)])
	d = [[INF] * w for i in range(h)]
	d[i0][j0] = 0
	while search:
		(i, j) = search.popleft()
		for (di, dj) in ((1, 0), (0, 1), (-1, 0), (0, -1)):
			(ni, nj) = (i + di, j + dj)
			if 0 <= ni < h and 0 <= nj < w and (s[ni][nj] == '.') and (d[ni][nj] == INF):
				search.append((ni, nj))
				d[ni][nj] = d[i][j] + 1
	return d[i][j]
max_d = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '.':
			max_dij = bfs(i, j)
			max_d = max(max_d, max_dij)
print(max_d)


from collections import deque
import copy
(H, W) = map(int, input().split())
S = [list(input()) for _ in range(H)]

def bfs(x, y):
	check = copy.deepcopy(S)
	que = deque()
	que.append((x, y))
	check[y][x] = 0
	while que.__len__() != 0:
		(x, y) = que.popleft()
		tmp = check[y][x]
		for (dx, dy) in ((1, 0), (-1, 0), (0, 1), (0, -1)):
			sx = x + dx
			sy = y + dy
			if -1 < sx < W and -1 < sy < H:
				if check[sy][sx] == '.':
					check[sy][sx] = tmp + 1
					que.append((sx, sy))
	return tmp
ans = 0
for x in range(W):
	for y in range(H):
		if S[y][x] == '.':
			ans = max(bfs(x, y), ans)
print(ans)


from copy import deepcopy
from collections import Counter, defaultdict, deque

def I():
	return int(input())

def LI():
	return list(map(int, input().split()))

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

def LLI(n):
	return [list(map(int, input().split())) for _ in range(n)]

def maze_solve(S_1, S_2, maze_list):
	d = deque()
	dist[S_1][S_2] = 0
	d.append([S_1, S_2])
	dx = [0, 0, 1, -1]
	dy = [1, -1, 0, 0]
	while d:
		v = d.popleft()
		x = v[0]
		y = v[1]
		for i in range(4):
			nx = x + dx[i]
			ny = y + dy[i]
			if nx < 0 or nx >= h or ny < 0 or (ny >= w):
				continue
			if dist[nx][ny] == -1:
				dist[nx][ny] = dist[x][y] + 1
				d.append([nx, ny])
	return max(list(map(lambda x: max(x), dist)))
(h, w) = MI()
ans = 0
maze = [list(input()) for _ in range(h)]
dist = [[-1] * w for _ in range(h)]
start_list = []
for i in range(h):
	for j in range(w):
		if maze[i][j] == '#':
			dist[i][j] = 0
		else:
			start_list.append([i, j])
dist_copy = deepcopy(dist)
for k in start_list:
	dist = deepcopy(dist_copy)
	ans = max(ans, maze_solve(k[0], k[1], maze))
print(ans)


from collections import deque
(H, W) = map(int, input().split())
area = ['#'] * (W + 2)
for i in range(H):
	area += ['#'] + list(input()) + ['#']
area += ['#'] * (W + 2)
H += 2
W += 2
move = [-1, 1, W, -W]
ans = 0
for i in range(H):
	for j in range(W):
		st = W * i + j
		if area[st] == '#':
			continue
		dq = deque([])
		dist = [-1] * (H * W)
		dq.append(st)
		dist[st] = 0
		while dq:
			now = dq.popleft()
			for dx in move:
				nxt = now + dx
				if dist[nxt] >= 0 or area[nxt] == '#':
					continue
				dist[nxt] = dist[now] + 1
				ans = max(ans, dist[nxt])
				dq.append(nxt)
print(ans)


from collections import deque
(H, W) = [int(x) for x in input().split()]
field = []
for i in range(H):
	field.append(input())
conn = [[[] for _ in range(W)] for _ in range(H)]
for i in range(H):
	for j in range(W):
		if field[i][j] == '.':
			for e in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
				(h, w) = (i + e[0], j + e[1])
				if 0 <= h < H and 0 <= w < W and (field[h][w] == '.'):
					conn[i][j].append([h, w])
d = 0
for i in range(H):
	for j in range(W):
		l = 0
		q = deque([[i, j]])
		dist = [[-1 for _ in range(W)] for _ in range(H)]
		dist[i][j] = 0
		while q:
			v = q.popleft()
			for w in conn[v[0]][v[1]]:
				if dist[w[0]][w[1]] == -1:
					q.append(w)
					dist[w[0]][w[1]] = dist[v[0]][v[1]] + 1
					l = dist[w[0]][w[1]]
		d = max(d, l)
print(d)


from collections import deque

def LI():
	return list(map(int, input().split()))

def LSH(h):
	return [input() for _ in range(h)]
(H, W) = LI()
Fi = LSH(H)
move = [[1, 0], [0, 1], [-1, 0], [0, -1]]
ans = 0
for sh in range(H):
	for sw in range(W):
		if Fi[sh][sw] == '#':
			continue
		d = deque()
		d.append([sh, sw])
		looked = [[0 for i in range(W)] for j in range(H)]
		looked[sh][sw] = 1
		while d:
			(h, w) = d.popleft()
			for i in move:
				a = h + i[0]
				b = w + i[1]
				if not 0 <= a < H or not 0 <= b < W or Fi[a][b] == '#' or (looked[a][b] != 0):
					continue
				d.append([a, b])
				looked[a][b] = looked[h][w] + 1
			if len(d) == 0:
				ans = max(ans, looked[h][w] - 1)
print(ans)


from collections import deque
from itertools import product
INF = 1001001001
dr = [(1, 0), (-1, 0), (0, 1), (0, -1)]
(H, W) = map(int, input().split())
S = [list(input()) for i in range(H)]
ans = 0
for (i, j) in product(range(H), range(W)):
	if S[i][j] == '#':
		continue
	d = [[INF] * W for i in range(H)]
	d[i][j] = 0
	q = deque([(i, j)])
	while len(q) > 0:
		(x, y) = q.popleft()
		for (dx, dy) in dr:
			(nx, ny) = (x + dx, y + dy)
			if 0 <= nx < H and 0 <= ny < W and (S[nx][ny] != '#') and (d[nx][ny] == INF):
				d[nx][ny] = d[x][y] + 1
				ans = max(d[nx][ny], ans)
				q.append((nx, ny))
print(ans)


(h, w) = map(int, input().split())
s = []
for _ in range(h):
	s_i = list(str(input()))
	s.append(s_i)

def connect(v):
	con_v = []
	if v[0] > 0:
		if s[v[0] - 1][v[1]] == '.':
			con_v.append((v[0] - 1, v[1]))
	if v[1] > 0:
		if s[v[0]][v[1] - 1] == '.':
			con_v.append((v[0], v[1] - 1))
	if v[0] < h - 1:
		if s[v[0] + 1][v[1]] == '.':
			con_v.append((v[0] + 1, v[1]))
	if v[1] < w - 1:
		if s[v[0]][v[1] + 1] == '.':
			con_v.append((v[0], v[1] + 1))
	return con_v
from heapq import heappush, heappop
INF = 10 ** 10
VISITED = 1
NOT_VISITED = 0

def longest_bfs(i, j):
	cost = [INF for _ in range(h * w)]
	cost[i * w + j] = 0
	visit = [NOT_VISITED for _ in range(h * w)]
	queue = [(0, (i, j))]
	while len(queue) > 0:
		(c, v) = heappop(queue)
		visit[v[0] * w + v[1]] = VISITED
		for u in connect(v):
			if visit[u[0] * w + u[1]] == VISITED:
				continue
			if cost[u[0] * w + u[1]] > cost[v[0] * w + v[1]] + 1:
				cost[u[0] * w + u[1]] = cost[v[0] * w + v[1]] + 1
				heappush(queue, (cost[u[0] * w + u[1]], u))
	return cost
longest_path = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '#':
			continue
		path_length = longest_bfs(i, j)
		for p in path_length:
			if p < INF and p > longest_path:
				longest_path = p
print(longest_path)


from collections import deque
from typing import List

def main():
	(h, w) = list(map(int, input().split()))
	g = []
	for _ in range(h):
		r = list(input())
		g.append(r)
	print(mm(h, w, g))

def mm(h: int, w: int, g: List[List[str]]) -> int:
	ret = 0
	for i in range(h):
		for j in range(w):
			if g[i][j] == '#':
				continue
			v = set()
			q = deque([(i, j, 0)])
			v.add((i, j))
			while q:
				(ii, jj, cnt) = q.popleft()
				ret = max(ret, cnt)
				if ii < h - 1 and g[ii + 1][jj] == '.' and ((ii + 1, jj) not in v):
					q.append((ii + 1, jj, cnt + 1))
					v.add((ii + 1, jj))
				if jj < w - 1 and g[ii][jj + 1] == '.' and ((ii, jj + 1) not in v):
					q.append((ii, jj + 1, cnt + 1))
					v.add((ii, jj + 1))
				if ii > 0 and g[ii - 1][jj] == '.' and ((ii - 1, jj) not in v):
					q.append((ii - 1, jj, cnt + 1))
					v.add((ii - 1, jj))
				if jj > 0 and g[ii][jj - 1] == '.' and ((ii, jj - 1) not in v):
					q.append((ii, jj - 1, cnt + 1))
					v.add((ii, jj - 1))
	return ret

def __starting_point():
	main()
__starting_point()


from collections import deque
(H, W) = map(int, input().split())
f = [[s == '.' for s in input()] for h in range(H)]
v = [[-1 for w in range(W)] for h in range(H)]
ans = 0
dh = [-1, 0, 0, 1]
dw = [0, 1, -1, 0]
for h in range(H):
	for w in range(W):
		if not f[h][w]:
			continue
		tmp = 0
		v = [[-1 for w in range(W)] for h in range(H)]
		Q = deque([(h, w)])
		v[h][w] = 0
		while Q:
			(nh, nw) = Q.popleft()
			for i in range(4):
				if 0 <= nh + dh[i] < H and 0 <= nw + dw[i] < W and f[nh + dh[i]][nw + dw[i]] and (v[nh + dh[i]][nw + dw[i]] == -1):
					v[nh + dh[i]][nw + dw[i]] = v[nh][nw] + 1
					tmp = v[nh + dh[i]][nw + dw[i]]
					Q.append((nh + dh[i], nw + dw[i]))
		ans = max(ans, tmp)
print(ans)


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

def bfs(sx, sy):
	dx = [1, 0, -1, 0]
	dy = [0, 1, 0, -1]
	d = [[-1] * W for _ in range(H)]
	q = deque([])
	q.append([sx, sy])
	d[sx][sy] = 0
	ans = 0
	while q:
		(x, y) = q.popleft()
		for i in range(4):
			nx = x + dx[i]
			ny = y + dy[i]
			if 0 <= nx < H and 0 <= ny < W and (S[nx][ny] != '#') and (d[nx][ny] == -1):
				q.append([nx, ny])
				d[nx][ny] = d[x][y] + 1
				ans = max(ans, d[nx][ny])
	return ans
ans = 0
for sh in range(H):
	if '.' in S[sh]:
		for sw in range(W):
			if S[sh][sw] == '.':
				ans = max(ans, bfs(sh, sw))
print(ans)


import sys
readline = sys.stdin.readline
(H, W) = map(int, readline().split())
S = [None] * H
for i in range(H):
	S[i] = readline().rstrip()
ans = 0
from collections import deque
cases = ((1, 0), (-1, 0), (0, 1), (0, -1))
for i in range(H):
	for j in range(W):
		q = deque([[i, j, 0]])
		seen = set()
		while q:
			(y, x, d) = q.popleft()
			if S[y][x] == '#':
				continue
			if (y, x) in seen:
				continue
			seen.add((y, x))
			if d > ans:
				ans = d
			for c in cases:
				if 0 <= y + c[0] < H and 0 <= x + c[1] < W:
					q.append([y + c[0], x + c[1], d + 1])
print(ans)


from collections import defaultdict, deque
(h, w) = map(int, input().split())
tizu = [input() for _ in range(h)]
ans = 0
directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
for i in range(h):
	for j in range(w):
		if tizu[i][j] == '#':
			continue
		check = [[False for _ in range(w)] for _ in range(h)]
		check[i][j] = True
		queue = deque()
		queue.append([i, j])
		queue.append(0)
		while queue:
			pos = queue.popleft()
			ans_sub = queue.popleft()
			for (dh, dw) in directions:
				nh = pos[0] + dh
				nw = pos[1] + dw
				if nh == -1 or nh == h or nw == -1 or (nw == w):
					continue
				if tizu[nh][nw] == '#':
					continue
				if check[nh][nw]:
					continue
				check[nh][nw] = True
				queue.append([nh, nw])
				queue.append(ans_sub + 1)
		ans = max(ans, ans_sub)
print(ans)


from collections import deque
import sys
input = sys.stdin.readline
(H, W) = map(int, input().split())
S = [input() for _ in range(H)]
ret = 0
for sy in range(H):
	for sx in range(W):
		if S[sy][sx] == '#':
			continue
		cost = [[float('inf')] * W for _ in range(H)]
		cost[sy][sx] = 0
		q = deque([(sy, sx, 0)])
		while q:
			(cy, cx, co) = q.popleft()
			for (dy, dx) in ((0, 1), (0, -1), (1, 0), (-1, 0)):
				(ny, nx) = (cy + dy, cx + dx)
				if 0 <= ny < H and 0 <= nx < W and (S[ny][nx] != '#') and (co + 1 < cost[ny][nx]):
					q.append((ny, nx, co + 1))
					cost[ny][nx] = co + 1
					ret = max(ret, co + 1)
print(ret)


from collections import deque
(h, w) = map(int, input().split())
l = [input() for _ in range(h)]
ma = 0
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

def bfs(sx, sy):
	if l[sy][sx] == '#':
		return 0
	d = [[float('inf')] * w for i in range(h)]
	que = deque([])
	que.append((sx, sy))
	d[sy][sx] = 0
	while que:
		p = que.popleft()
		for i in range(4):
			nx = p[0] + dx[i]
			ny = p[1] + dy[i]
			if 0 <= nx < w and 0 <= ny < h and (l[ny][nx] != '#') and (d[ny][nx] == float('inf')):
				que.append((nx, ny))
				d[ny][nx] = d[p[1]][p[0]] + 1
				gx = nx
				gy = ny
	return d[gy][gx]
for i in range(h):
	for k in range(w):
		ma = max(ma, bfs(k, i))
print(ma)


import heapq
(H, W) = map(int, input().split())
area = ['#'] * (W + 2)
for i in range(H):
	area += ['#'] + list(input()) + ['#']
area += ['#'] * (W + 2)
H += 2
W += 2
move = [-1, 1, W, -W]
ans = 0
for i in range(H):
	for j in range(W):
		st = W * i + j
		if area[st] == '#':
			continue
		hq = []
		dist = [-1] * (H * W)
		dist[st] = 0
		heapq.heappush(hq, (0, st))
		while hq:
			(cost, now) = heapq.heappop(hq)
			for dx in move:
				nxt = now + dx
				if dist[nxt] >= 0 or area[nxt] == '#':
					continue
				dist[nxt] = dist[now] + 1
				ans = max(ans, dist[nxt])
				heapq.heappush(hq, (dist[nxt], nxt))
print(ans)


from collections import *
from copy import *
(H, W) = map(int, input().split())
S = [(W + 2) * ['#']] + [['#'] + list(input()) + ['#'] for h in range(H)] + [(W + 2) * ['#']]
D = [[1, 0], [-1, 0], [0, 1], [0, -1]]
ans = 0
P = deque([])
Q = deque([])
for h in range(1, H + 1):
	for w in range(1, W + 1):
		if S[h][w] == '.':
			P += [[h, w]]
while P:
	T = deepcopy(S)
	(sx, sy) = P.popleft()
	T[sx][sy] = 0
	Q = deque([[sx, sy]])
	while Q:
		(x, y) = Q.popleft()
		for (dx, dy) in D:
			if T[x + dx][y + dy] == '.':
				T[x + dx][y + dy] = T[x][y] + 1
				Q += [[x + dx, y + dy]]
				ans = max(ans, T[x + dx][y + dy])
print(ans)


from collections import deque
(H, W) = map(int, input().split())
field = [list(input()) for _ in range(H)]
dist = [[-1] * W for _ in range(H)]
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
mx = 0
for h in range(H):
	for w in range(W):
		if field[h][w] == '#':
			continue
		dist = [[-1] * W for _ in range(H)]
		dist[h][w] = 0
		que = deque([])
		que.append([h, w])
		while que != deque([]):
			(u, v) = que.popleft()
			for dir in range(4):
				nu = u + dx[dir]
				nv = v + dy[dir]
				if nu < 0 or nu >= H or nv < 0 or (nv >= W):
					continue
				if field[nu][nv] == '#':
					continue
				if dist[nu][nv] != -1:
					continue
				que.append([nu, nv])
				dist[nu][nv] = dist[u][v] + 1
		for i in range(H):
			for j in range(W):
				if mx < dist[i][j]:
					mx = dist[i][j]
print(mx)


from collections import deque

def bfs(yy, xx):
	global ans
	d = [[float('inf')] * w for i in range(h)]
	dx = [1, 0, -1, 0]
	dy = [0, 1, 0, -1]
	q = deque([])
	q.append((yy, xx))
	d[yy][xx] = 0
	while q:
		(y, x) = q.popleft()
		for i in range(4):
			(ny, nx) = (y + dy[i], x + dx[i])
			if 0 <= ny < h and 0 <= nx < w and (s[ny][nx] == '.') and (d[ny][nx] == float('inf')):
				d[ny][nx] = d[y][x] + 1
				q.append((ny, nx))
				if ans < d[ny][nx]:
					ans = d[ny][nx]
	return ans
(h, w) = map(int, input().split())
s = [list(input()) for i in range(h)]
a = 0
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '.':
			a = max(a, bfs(i, j))
print(a)


def main():
	from collections import deque
	import numpy as np
	(H, W) = list(map(int, input().split()))
	S = [list(input()) for _ in range(H)]
	move = ((0, 1), (0, -1), (1, 0), (-1, 0))
	seen = [[False] * W for _ in range(H)]
	ans = 0
	for sh in range(H):
		for sw in range(W):
			if S[sh][sw] == '#' or seen[sh][sw]:
				continue
			seen[sh][sw] = True
			queue = deque([(sh, sw)])
			distance = np.full((H, W), -1, dtype=np.int16)
			distance[sh, sw] = 0
			while queue:
				(h, w) = queue.popleft()
				for (dh, dw) in move:
					nh = h + dh
					nw = w + dw
					if 1 and 0 <= nh < H and (0 <= nw < W) and (S[nh][nw] == '.') and (distance[nh][nw] == -1):
						distance[nh][nw] = distance[h][w] + 1
						queue.append((nh, nw))
			ans = max(ans, distance.max())
	print(ans)

def __starting_point():
	main()
__starting_point()


from collections import deque
(h, w) = map(int, input().split())
G = [input() for i in range(h)]
directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]
ans = 0
for sx in range(w):
	for sy in range(h):
		if G[sy][sx] == '#':
			continue
		dist = [[-1] * w for i in range(h)]
		dist[sy][sx] = 0
		que = deque([[sy, sx]])
		while len(que):
			(y, x) = que.popleft()
			for (dx, dy) in directions:
				nx = x + dx
				ny = y + dy
				if not (0 <= nx < w and 0 <= ny < h) or G[ny][nx] == '#':
					continue
				if dist[ny][nx] != -1:
					continue
				dist[ny][nx] = dist[y][x] + 1
				que.append([ny, nx])
		ans = max(ans, max([max(d) for d in dist]))
print(ans)


import heapq

def abc151d_maze_master():
	(h, w) = map(int, input().split())
	s = []
	max_val = 0
	for i in range(h):
		s.append(input())
	for hi in range(h):
		for wi in range(w):
			if s[hi][wi] == '#':
				continue
			flg = [[-1] * w for _ in range(h)]
			flg[hi][wi] = 0
			q = [(0, hi, wi)]
			heapq.heapify(q)
			while len(q) > 0:
				(d, hj, wj) = heapq.heappop(q)
				for (dh, dw) in zip([0, 0, 1, -1], [1, -1, 0, 0]):
					if 0 <= hj + dh < h and 0 <= wj + dw < w and (s[hj + dh][wj + dw] != '#') and (flg[hj + dh][wj + dw] == -1 or flg[hj + dh][wj + dw] > flg[hj][wj] + 1):
						heapq.heappush(q, (d + 1, hj + dh, wj + dw))
						flg[hj + dh][wj + dw] = flg[hj][wj] + 1
			max_val = max(max_val, max([max(v) for v in flg]))
	print(max_val)
abc151d_maze_master()


from collections import deque
(H, W) = list(map(int, input().split()))
S = [[c == '#' for c in input()] for _ in range(H)]

def bfs(i, j):
	if S[i][j]:
		return 0
	que = deque()
	que.append((i, j))
	vis = [row[:] for row in S]
	vis[i][j] = 1
	ans = -1
	while que:
		ans += 1
		for _ in range(len(que)):
			(i, j) = que.popleft()
			for (ni, nj) in nbs(i, j):
				if not vis[ni][nj]:
					que.append((ni, nj))
					vis[ni][nj] = 1
	return ans

def nbs(i, j):
	for (ni, nj) in ((i - 1, j), (i, j + 1), (i + 1, j), (i, j - 1)):
		if 0 <= ni < H and 0 <= nj < W:
			yield (ni, nj)
ans = 0
for i in range(H):
	for j in range(W):
		ans = max(ans, bfs(i, j))
print(ans)


from collections import deque
(h, w) = list(map(int, input().split()))
grid = [input() for _ in range(h)]
ans = 0
for startx in range(w):
	for starty in range(h):
		if grid[starty][startx] == '#':
			continue
		dist = [[10000] * w for _ in range(h)]
		dist[starty][startx] = 0
		maxDist = 0
		q = deque([(startx, starty)])
		while q:
			(curx, cury) = q.popleft()
			adj = [(1, 0), (-1, 0), (0, 1), (0, -1)]
			for (xo, yo) in adj:
				(x, y) = (curx + xo, cury + yo)
				if x < 0 or x >= w or y < 0 or (y >= h):
					continue
				if grid[y][x] == '#':
					continue
				newDist = dist[cury][curx] + 1
				if newDist < dist[y][x]:
					dist[y][x] = newDist
					q.append((x, y))
					maxDist = max(maxDist, newDist)
		ans = max(ans, maxDist)
print(ans)


from collections import deque
import copy

def BFS(sy, sx, xy_list):
	dist = [[-1] * w for i in range(h)]
	dist[sy][sx] = 0
	xy_list[sy][sx] = '#'
	dq = deque()
	dq.append((sy, sx))
	while dq:
		(y, x) = dq.popleft()
		for (dy, dx) in [[1, 0], [-1, 0], [0, 1], [0, -1]]:
			ny = y + dy
			nx = x + dx
			if 0 <= ny < h and 0 <= nx < w and (xy_list[ny][nx] != '#'):
				dq.append((ny, nx))
				xy_list[ny][nx] = '#'
				dist[ny][nx] = dist[y][x] + 1
	return dist
(h, w) = map(int, input().split())
s = [list(input()) for i in range(h)]
ans = 0
for hh in range(h):
	for ww in range(w):
		if s[hh][ww] == '#':
			continue
		xy_list = copy.deepcopy(s)
		dist = BFS(hh, ww, xy_list)
		for d in dist:
			ans = max(ans, max(d))
print(ans)


from collections import *
from itertools import *
(h, w) = map(int, input().split())
maze = [input() for _ in range(h)]
dest = [(1, 0), (-1, 0), (0, 1), (0, -1)]
score = 0
for (sx, sy) in product(range(w), range(h)):
	if maze[sy][sx] == '#':
		continue
	r = [[-1] * w for _ in range(h)]
	r[sy][sx] = 0
	queue = deque([(sx, sy)])
	while queue:
		(x, y) = queue.popleft()
		for (dx, dy) in dest:
			(nx, ny) = (x + dx, y + dy)
			if not (0 <= nx < w and 0 <= ny < h):
				continue
			if maze[ny][nx] == '#' or r[ny][nx] != -1:
				continue
			r[ny][nx] = r[y][x] + 1
			queue.append((nx, ny))
			score = max(score, r[ny][nx])
print(score)


from collections import deque
(n, m) = map(int, input().split())
maze = [['#'] + list(input()) + ['#'] for i in range(n)]
maze = [['#'] * (m + 2)] + maze + [['#'] * (m + 2)]
step = [(0, 1), (1, 0), (-1, 0), (0, -1)]
costma = 0
for i in range(1, n + 1):
	for j in range(1, m + 1):
		v = [[0] * (m + 2) for i in range(n + 2)]
		d = deque()
		d.append((i, j, 0))
		v[i][j] = 1
		while d:
			(y, x, cost) = d.popleft()
			if maze[y][x] == '.':
				for (dy, dx) in step:
					if maze[y + dy][x + dx] == '.' and v[y + dy][x + dx] == 0:
						v[y + dy][x + dx] = 1
						d.append((y + dy, x + dx, cost + 1))
						costma = max(cost + 1, costma)
print(costma)


(H, W) = map(int, input().split())
s = []
for _ in range(H):
	s.append(list(input()))

def dfs(y, x):
	q = [(y, x)]
	visited = [[-1] * W for _ in range(H)]
	visited[y][x] = 0
	while q:
		(cy, cx) = q.pop(0)
		for (dy, dx) in ((1, 0), (-1, 0), (0, -1), (0, 1)):
			nx = cx + dx
			ny = cy + dy
			if 0 <= ny < H and 0 <= nx < W and (s[ny][nx] == '.') and (visited[ny][nx] == -1):
				visited[ny][nx] = visited[cy][cx] + 1
				q.append((ny, nx))
	return max((max(i) for i in visited))
ans = 0
for h in range(H):
	for w in range(W):
		if s[h][w] == '.':
			ans = max(dfs(h, w), ans)
print(ans)


import sys
from collections import deque
input = sys.stdin.readline
(h, w) = map(int, input().split())
M = [list(input().strip()) for _ in range(h)]

def bfs(x, y):
	if M[x][y] == '#':
		return 0
	q = deque()
	q.append((x, y))
	count = [[-1] * w for _ in range(h)]
	count[x][y] = 0
	while q:
		(x, y) = q.pop()
		for (i, j) in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
			if 0 <= i < h and 0 <= j < w and (count[i][j] == -1) and (M[i][j] == '.'):
				count[i][j] = count[x][y] + 1
				q.appendleft((i, j))
	return max([max(c) for c in count])
ans = 0
for i in range(h):
	for j in range(w):
		ans = max(ans, bfs(i, j))
print(ans)


from collections import deque
inf = 401
(H, W) = map(int, input().split(' '))
maze = [list(input()) for i in range(H)]
ans = 0

def short_long(a, b):
	q = deque()
	q.append((a, b))
	d = [[inf for i in range(W)] for j in range(H)]
	d[a][b] = 0
	tmp = 0
	while q:
		(x, y) = q.popleft()
		for (i, j) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
			(nx, ny) = (x + i, y + j)
			if 0 <= nx < H and 0 <= ny < W and (maze[nx][ny] != '#') and (d[nx][ny] == inf):
				q.append((nx, ny))
				d[nx][ny] = d[x][y] + 1
				tmp = max(d[nx][ny], tmp)
	return tmp
for i in range(H):
	for j in range(W):
		if maze[i][j] == '.':
			ans = max(ans, short_long(i, j))
print(ans)


import sys
sys.setrecursionlimit(10 ** 7)
from collections import deque

def resolve():

	def bfs(sy, sx):
		q = deque()
		q.append((sy, sx))
		dist = [[-1] * (W + 2) for _ in range(H + 2)]
		dist[sy][sx] = 0
		drc = [(-1, 0), (0, 1), (1, 0), (0, -1)]
		while q:
			(sy, sx) = q.popleft()
			for (dy, dx) in drc:
				ny = dy + sy
				nx = dx + sx
				if G[ny][nx] == '.' and dist[ny][nx] == -1:
					dist[ny][nx] = dist[sy][sx] + 1
					q.append((ny, nx))
			if not q:
				return dist[sy][sx]
	(H, W) = list(map(int, input().split()))
	G = []
	G.append(['#'] * (W + 2))
	G += [['#'] + list(input()) + ['#'] for _ in range(H)]
	G.append(['#'] * (W + 2))
	ans = 0
	for i in range(1, H + 1):
		for j in range(1, W + 1):
			if G[i][j] == '#':
				continue
			ans = max(ans, bfs(i, j))
	print(ans)

def __starting_point():
	resolve()
__starting_point()


from collections import deque
(h, w) = map(int, input().split())
maze = [list(input()) for i in range(h)]
ans = 0
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
for i in range(h):
	for j in range(w):
		Q = deque()
		Q.append((i, j, 0))
		if maze[i][j] == '#':
			continue
		dp = [[-1] * w for i in range(h)]
		dp[i][j] = 0
		while Q:
			p = Q.popleft()
			ans = max(ans, p[2])
			for k in range(4):
				nx = p[0] + dx[k]
				ny = p[1] + dy[k]
				if 0 <= nx < h and 0 <= ny < w and (maze[nx][ny] == '.') and (dp[nx][ny] == -1):
					Q.append((nx, ny, p[2] + 1))
					dp[nx][ny] = p[2] + 1
print(ans)


(h, w) = map(int, input().split())
b = [[1] * (w + 2)]
for i in range(h):
	bb = [1]
	s = input()
	for j in range(w):
		if s[j] == '#':
			bb.append(1)
		else:
			bb.append(0)
	bb.append(1)
	b.append(bb)
b.append([1] * (w + 2))
ans = 0
d = [[-1, 0], [1, 0], [0, -1], [0, 1]]
for si in range(1, h + 1):
	for sj in range(1, w + 1):
		if b[si][sj]:
			continue
		visited = {(si, sj)}
		Q = [(si, sj)]
		count = -1
		while Q:
			P = []
			for (i, j) in Q:
				for (di, dj) in d:
					if b[i + di][j + dj]:
						continue
					if (i + di, j + dj) in visited:
						continue
					visited.add((i + di, j + dj))
					P.append((i + di, j + dj))
			Q = P
			count += 1
		ans = max(ans, count)
print(ans)


from collections import deque
(h, w) = map(int, input().split())
s = ['#' * (w + 2)] + ['#' + input() + '#' for _ in range(h)] + ['#' * (w + 2)]
ans = 0
INF = 111111
for i in range(h + 1):
	for j in range(w + 1):
		if s[i][j] == '#':
			continue
		visited = [[0] * (w + 2) for _ in range(h + 2)]
		visited[i][j] = 1
		max_s = 0
		dq = deque([(i, j, 0)])
		while dq:
			(ci, cj, step) = dq.popleft()
			if step > max_s:
				max_s = step
			step += 1
			for (di, dj) in ((ci + 1, cj), (ci, cj + 1), (ci - 1, cj), (ci, cj - 1)):
				if s[di][dj] == '#' or visited[di][dj] == 1:
					continue
				visited[di][dj] = 1
				dq.append((di, dj, step))
		ans = max(max_s, ans)
print(ans)


from collections import deque
(H, W) = [int(v) for v in input().split()]
S = ['#' + input() + '#' for _ in range(H)]
S.insert(0, '#' * (W + 2))
S.append('#' * (W + 2))
ans = 0
for y in range(1, H + 1):
	for x in range(1, W + 1):
		if S[y][x] == '#':
			continue
		queue = deque([[x, y, 0]])
		visited = [[False] * (W + 2) for _ in range(H + 2)]
		visited[y][x] = True
		while queue:
			(x, y, c) = queue.pop()
			for (ny, nx) in [[y + 1, x], [y, x + 1], [y - 1, x], [y, x - 1]]:
				if visited[ny][nx] or S[ny][nx] == '#':
					continue
				visited[ny][nx] = True
				queue.appendleft([nx, ny, c + 1])
			ans = max(ans, c)
print(ans)


(h, w) = map(int, input().split())
ls = [input() for _ in range(h)]
from collections import deque
a = 0
for i in range(h):
	for j in range(w):
		if ls[i][j] == '#':
			continue
		d = [[-1] * w for _ in range(h)]
		d[i][j] = 0
		q = deque([(i, j)])
		while q:
			(x, y) = q.popleft()
			for (dx, dy) in ((1, 0), (0, 1), (-1, 0), (0, -1)):
				(nx, ny) = (x + dx, y + dy)
				if not (0 <= nx < h and 0 <= ny < w):
					continue
				if ls[nx][ny] == '.' and d[nx][ny] == -1:
					d[nx][ny] = d[x][y] + 1
					q.append((nx, ny))
		a = max(a, max((max((j for j in i)) for i in d)))
print(a)


(h, w) = map(int, input().split())
s = [input() for _ in range(h)]
from collections import deque
ans = 0
dd = [(1, 0), (-1, 0), (0, 1), (0, -1)]
for i in range(h):
	for j in range(w):
		if s[i][j] == '#':
			continue
		g = [[0] * w for _ in range(h)]
		v = [[0] * w for _ in range(h)]
		g[i][j] = 1
		q = deque([(j, i)])
		while q:
			(x, y) = q.popleft()
			for (dx, dy) in dd:
				nx = x + dx
				ny = y + dy
				if not 0 <= nx < w:
					continue
				if not 0 <= ny < h:
					continue
				if g[ny][nx]:
					continue
				if s[ny][nx] == '#':
					continue
				g[ny][nx] = 1
				v[ny][nx] = v[y][x] + 1
				q.append((nx, ny))
		for ii in v:
			ans = max(ans, max(ii))
print(ans)


from collections import deque

def bfs(maze, sy, sx):
	queue = deque([[sy, sx]])
	visited = [[0] * w for _ in range(h)]
	visited[sy][sx] = 1
	mx = 0
	while queue:
		(y, x) = queue.popleft()
		for (j, k) in ([1, 0], [-1, 0], [0, 1], [0, -1]):
			(n_y, n_x) = (y + j, x + k)
			if not (0 <= n_y < h and 0 <= n_x < w):
				continue
			if maze[n_y][n_x] == '.' and visited[n_y][n_x] == 0:
				visited[n_y][n_x] = visited[y][x] + 1
				mx = max(mx, visited[n_y][n_x])
				queue.append([n_y, n_x])
	return mx
(h, w) = map(int, input().split())
s = [input() for _ in range(h)]
ans = 0
for sy in range(h):
	for sx in range(w):
		if s[sy][sx] == '#':
			continue
		ans = max(ans, bfs(s, sy, sx) - 1)
print(ans)


from collections import deque

def bfs(y, x):
	q = deque([(y, x)])
	visited[y][x] = 0
	while q:
		(cy, cx) = q.popleft()
		for (dy, dx) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
			(ny, nx) = (cy + dy, cx + dx)
			if 0 <= ny < h and 0 <= nx < w and (visited[ny][nx] == -1):
				if s[ny][nx] == '#':
					continue
				visited[ny][nx] = visited[cy][cx] + 1
				q.append((ny, nx))
	res = 0
	for i in range(h):
		for j in range(w):
			if s[i][j] != '#':
				res = max(res, visited[i][j])
	return res
(h, w) = map(int, input().split())
s = [input() for _ in range(h)]
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '#':
			continue
		sh = i
		sw = j
		visited = [[-1] * w for _ in range(h)]
		ans = max(ans, bfs(sh, sw))
print(ans)


(n, m) = map(int, input().split())
grid = [input() for i in range(n)]
res = 0
dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]
for a in range(n):
	for b in range(m):
		if grid[a][b] != '.':
			continue
		vis = set([(a, b)])
		q = [(a, b, 0)]
		qi = 0
		while qi < len(q):
			(i, j, c) = q[qi]
			res = max(res, c)
			qi += 1
			for (di, dj) in dirs:
				(ni, nj) = (i + di, j + dj)
				if (ni, nj) in vis or ni < 0 or ni >= n or (nj < 0) or (nj >= m) or (grid[ni][nj] != '.'):
					continue
				vis.add((ni, nj))
				q.append((ni, nj, c + 1))
print(res)


(H, W) = map(int, input().split())
S = []
for _ in range(H):
	S.append(input())
import queue, itertools
dxy = ((1, 0), (-1, 0), (0, 1), (0, -1))
ans = 0
for s in itertools.product(range(H), range(W)):
	if S[s[0]][s[1]] == '#':
		continue
	q = queue.Queue()
	dist = [[-1] * W for _ in range(H)]
	q.put(s)
	dist[s[0]][s[1]] = 0
	while not q.empty():
		(y, x) = q.get()
		for (dx, dy) in dxy:
			(nx, ny) = (x + dx, y + dy)
			if nx < 0 or ny < 0 or nx >= W or (ny >= H) or (S[ny][nx] == '#') or (dist[ny][nx] >= 0):
				continue
			dist[ny][nx] = dist[y][x] + 1
			q.put((ny, nx))
	ans = max(ans, max(map(max, dist)))
print(ans)


from collections import deque
import copy
(H, W) = map(int, input().split())
start = set()
for y in range(H):
	for (x, w) in enumerate(input()):
		if w == '.':
			start.add((x, y))
score = 0
ssize = [(-1, 0), (0, -1), (1, 0), (0, 1)]
for xy in start:
	d = deque()
	d.append(xy + (0,))
	step = 0
	can = copy.deepcopy(start)
	can.remove(xy)
	while len(d) > 0:
		now = d.popleft()
		step = now[2]
		for (xs, ys) in ssize:
			nxt = (now[0] + xs, now[1] + ys)
			if nxt in can:
				d.append(nxt + (step + 1,))
				can.remove(nxt)
	score = max(step, score)
print(score)


from collections import deque

def BFS(s):
	q = deque()
	q.append(s)
	dist = [[10 ** 10] * (W + 2) for _ in range(H + 2)]
	dist[s[0]][s[1]] = 0
	d = ((0, 1), (0, -1), (1, 0), (-1, 0))
	far = []
	while len(q) > 0:
		(i, j) = q.popleft()
		for (di, dj) in d:
			if field[i + di][j + dj] == '.' and dist[i + di][j + dj] == 10 ** 10:
				q.append([i + di, j + dj])
				dist[i + di][j + dj] = dist[i][j] + 1
		res = dist[i][j]
	return res
(H, W) = map(int, input().split())
field = ['#' * (W + 2)]
field += ['#' + input() + '#' for _ in range(H)]
field += ['#' * (W + 2)]
res = 0
for i in range(H + 2):
	for j in range(W + 2):
		if field[i][j] == '.':
			s = [i, j]
			res = max(res, BFS(s))
print(res)


from collections import deque
(h, w) = map(int, input().split())
l = [list(input()) for _ in range(h)]
ans = 0

def bfs(y, x, m):
	g = [[None if l[i][j] == '.' else -1 for j in range(w)] for i in range(h)]
	g[y][x] = 0
	q = deque()
	q.append((y, x))
	while q:
		(i, j) = q.popleft()
		for (di, dj) in ((0, 1), (1, 0), (-1, 0), (0, -1)):
			ni = i + di
			nj = j + dj
			if 0 <= ni < h and 0 <= nj < w and (g[ni][nj] is None):
				g[ni][nj] = g[i][j] + 1
				q.append((ni, nj))
	return max((max(r) for r in g))
for i in range(h):
	for j in range(w):
		if l[i][j] == '.':
			d = bfs(i, j, l)
			if ans < d:
				ans = d
print(ans)


import sys
readline = sys.stdin.readline
(H, W) = map(int, readline().split())
grid = [readline().rstrip() for i in range(H)]
ans = 0
cases = ((0, 1), (0, -1), (1, 0), (-1, 0))
from collections import deque
for i in range(H):
	for j in range(W):
		q = deque([[i, j, 0]])
		visited = [[False] * W for i in range(H)]
		while q:
			(y, x, d) = q.popleft()
			if grid[y][x] == '#':
				continue
			if visited[y][x]:
				continue
			visited[y][x] = True
			if d > ans:
				ans = d
			for c in cases:
				if 0 <= y + c[0] < H and 0 <= x + c[1] < W:
					q.append([y + c[0], x + c[1], d + 1])
print(ans)


from collections import deque
import copy
(H, W) = map(int, input().split())
inf = 1000000000
field = []
for i in range(H):
	row = list(input())
	for j in range(len(row)):
		if row[j] == '#':
			row[j] = -1
		else:
			row[j] = inf
	field.append(row)
ans = inf

def isIn(x, y):
	if x < 0 or x >= W:
		return False
	if y < 0 or y >= H:
		return False
	return True
vector = [[0, 1], [0, -1], [1, 0], [-1, 0]]
ans = 0
for i in range(H):
	for j in range(W):
		if field[i][j] == -1:
			continue
		l = deque([[j, i]])
		f = copy.deepcopy(field)
		f[i][j] = 0
		tmp = 0
		while l:
			(x, y) = l.popleft()
			for v in vector:
				if not isIn(x + v[1], y + v[0]):
					continue
				if f[y + v[0]][x + v[1]] <= tmp:
					continue
				f[y + v[0]][x + v[1]] = f[y][x] + 1
				l.append([x + v[1], y + v[0]])
				tmp = max(f[y + v[0]][x + v[1]], tmp)
		ans = max(ans, tmp)
print(ans)


import queue
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
(H, W) = map(int, input().split())
S = []
for h in range(H):
	S.append(input())

def bfs(s):
	dist = [[-1] * W for _ in range(H)]
	(h, w) = s
	dist[h][w] = 0
	que = queue.Queue()
	que.put(s)
	while not que.empty():
		(h, w) = que.get()
		for d in range(4):
			nh = h + dx[d]
			nw = w + dy[d]
			if nh < 0 or H <= nh or nw < 0 or (W <= nw):
				continue
			if S[nh][nw] == '#':
				continue
			if dist[nh][nw] == -1:
				dist[nh][nw] = dist[h][w] + 1
				que.put([nh, nw])
	return dist[h][w]
ans = 0
for h in range(H):
	for w in range(W):
		if S[h][w] == '.':
			ans = max(ans, bfs([h, w]))
print(ans)


from collections import *
from copy import *
(n, m) = map(int, input().split())
grid = [list('#' * (m + 2))] + [list('#' + input() + '#') for i in range(n)] + [list('#' * (m + 2))]
start = []
for i in range(1, n + 1):
	for j in range(1, m + 1):
		start.append((i, j))
ans = 0
for s in start:
	G = deepcopy(grid)
	if G[s[0]][s[1]] != '#':
		G[s[0]][s[1]] = 0
	else:
		continue
	Q = deque([s])
	while Q:
		(y, x) = Q.pop()
		for (my, mx) in ((-1, 0), (1, 0), (0, -1), (0, 1)):
			if G[y + my][x + mx] == '.':
				G[y + my][x + mx] = G[y][x] + 1
				Q.appendleft((y + my, x + mx))
	x = max((max([0] + [j for j in i if type(j) == int]) for i in G))
	if x > ans:
		ans = x
print(ans)


from collections import deque
import copy
(H, W) = map(int, input().split())
MAP = [list(input()) for y in range(H)]

def Maze(_x, _y):
	MAP2 = copy.deepcopy(MAP)
	q = deque([[_x, _y]])
	MAP2[_y][_x] = 0
	while q:
		xy = q.popleft()
		for d in [(0, -1), (-1, 0), (0, 1), (1, 0)]:
			(x2, y2) = (xy[0] + d[0], xy[1] + d[1])
			if x2 < 0 or y2 < 0 or x2 >= W or (y2 >= H):
				continue
			if MAP2[y2][x2] == '.':
				q.append([x2, y2])
				MAP2[y2][x2] = MAP2[xy[1]][xy[0]] + 1
	maxM = 0
	for y in range(H):
		for x in range(W):
			if type(MAP2[y][x]) == int:
				maxM = max(maxM, MAP2[y][x])
	return maxM
ans = 0
for y in range(H):
	for x in range(W):
		if MAP[y][x] == '.':
			ans = max(ans, Maze(x, y))
print(ans)


from queue import deque
(H, W) = map(int, input().split())
S = list((list(input()) for _ in range(H)))
ans = 0
for h in range(H):
	for w in range(W):
		if S[h][w] == '.':
			D = [[-1] * W for _ in range(H)]
			D[h][w] = 0
			Q = deque()
			Q.append((h, w))
			while Q:
				(y, x) = Q.popleft()
				for (i, j) in ((1, 0), (-1, 0), (0, 1), (0, -1)):
					(y2, x2) = (y + i, x + j)
					if 0 <= y2 < H and 0 <= x2 < W and (S[y2][x2] == '.') and (D[y2][x2] == -1):
						Q.append((y2, x2))
						D[y2][x2] = D[y][x] + 1
			for i in range(H):
				ans = max(ans, max(D[i]))
print(ans)


(H, W) = map(int, input().split())
S = []
for i in range(H):
	S.append(input())

def bfs(start):
	already = {}
	queue = []
	counter = 0
	queue.append((start[0], start[1], 0))
	already[start] = True
	max_depth = 0
	while counter < len(queue):
		(y, x, depth) = queue[counter]
		if depth > max_depth:
			max_depth = depth
		for move in ((-1, 0), (0, 1), (1, 0), (0, -1)):
			new_y = y + move[0]
			new_x = x + move[1]
			if new_y >= 0 and new_y < H and (new_x >= 0) and (new_x < W) and (S[new_y][new_x] == '.') and ((new_y, new_x) not in already):
				already[new_y, new_x] = True
				queue.append((new_y, new_x, depth + 1))
		counter += 1
	return max_depth
answer = 0
for i in range(H):
	for j in range(W):
		if S[i][j] == '#':
			continue
		depth = bfs((i, j))
		if answer < depth:
			answer = depth
print(answer)


(h, w) = [int(x) for x in input().rstrip().split()]
l = [list(input()) for i in range(h)]
move = [[1, 0], [-1, 0], [0, -1], [0, 1]]

def bfs(x, y):
	stack = [[x, y]]
	done = [[False] * w for i in range(h)]
	dist = [[0] * w for i in range(h)]
	max_val = 0
	while stack:
		(nx, ny) = stack.pop(0)
		done[ny][nx] = True
		for (dx, dy) in move:
			mx = nx + dx
			my = ny + dy
			if not 0 <= mx <= w - 1 or not 0 <= my <= h - 1 or done[my][mx] == True or (l[my][mx] == '#'):
				continue
			done[my][mx] = True
			dist[my][mx] = dist[ny][nx] + 1
			max_val = max(max_val, dist[my][mx])
			stack.append([mx, my])
	return max_val
ans = 0
for i in range(w):
	for j in range(h):
		if l[j][i] != '#':
			now = bfs(i, j)
			ans = max(ans, now)
print(ans)


(h, w) = map(int, input().split())
s = [list(input()) for _ in range(h)]
dyx = [(1, 0), (-1, 0), (0, 1), (0, -1)]
from collections import deque
q = deque()
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '#':
			continue
		q.append((i, j))
		d = [[0] * w for _ in range(h)]
		while q:
			(y, x) = q.popleft()
			for (dy, dx) in dyx:
				(ny, nx) = (y + dy, x + dx)
				if ny == i and nx == j:
					continue
				if 0 <= ny < h and 0 <= nx < w and (d[ny][nx] == 0) and (s[ny][nx] == '.'):
					d[ny][nx] = d[y][x] + 1
					q.append((ny, nx))
		for k in range(h):
			ans = max(ans, max(d[k]))
print(ans)


from collections import deque
(h, w) = list(map(int, input().split()))
s = []
s.append(list('#' * (w + 2)))
start = []
for i in range(1, h + 1):
	wk = list('#' + input() + '#')
	for j in range(1, w + 1):
		if wk[j] == '.':
			start.append([i, j])
	s.append(wk)
s.append(list('#' * (w + 2)))
dist = [[-1] * (w + 2) for _ in range(h + 2)]

def bfs(start):
	que = deque([start])
	dist[start[0]][start[1]] = 0
	end = []
	cnt = 0
	while que:
		(y, x) = que.popleft()
		for (py, px) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
			(ny, nx) = (y + py, x + px)
			if s[ny][nx] == '.' and dist[ny][nx] == -1:
				dist[ny][nx] = dist[y][x] + 1
				que.append([ny, nx])
				cnt = max(cnt, dist[y][x] + 1)
	return cnt
ans = 0
for i in start:
	ans = max(ans, bfs(i))
	dist = [[-1] * (w + 2) for _ in range(h + 2)]
print(ans)


from collections import deque
(h, w) = list(map(int, input().split()))
s = [input() for _ in range(h)]
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

def bfs(i, j):
	cost = [[-1 for _ in range(w)] for _ in range(h)]
	que = deque()
	cost[i][j] = 0
	que.append((i, j))
	if s[i][j] == '#':
		return 0
	while que:
		(ni, nj) = que.popleft()
		for k in range(4):
			if 0 <= ni + dy[k] < h and 0 <= nj + dx[k] < w:
				if cost[ni + dy[k]][nj + dx[k]] != -1:
					continue
				if s[ni + dy[k]][nj + dx[k]] == '.':
					cost[ni + dy[k]][nj + dx[k]] = cost[ni][nj] + 1
					que.append((ni + dy[k], nj + dx[k]))
	cc = 0
	for i in range(h):
		for j in range(w):
			if cost[i][j] > cc:
				cc = cost[i][j]
	return cc
ans = 0
for i in range(h):
	for j in range(w):
		cost = bfs(i, j)
		ans = max(ans, cost)
print(ans)


from collections import deque
(h, w) = map(int, input().split())
maze = []
for _ in range(h):
	maze.append(input())
ans = 0
move = [[1, 0], [-1, 0], [0, 1], [0, -1]]
for i in range(h):
	for j in range(w):
		if maze[i][j] == '.':
			dist = [[99999999] * w for _ in range(h)]
			dq = deque()
			y = i
			x = j
			d = 0
			dist[y][x] = 0
			dq.append((y, x, d))
			while len(dq):
				(y, x, d) = dq.popleft()
				for m in move:
					if 0 <= x + m[0] < w and 0 <= y + m[1] < h and (dist[y + m[1]][x + m[0]] > d + 1) and (maze[y + m[1]][x + m[0]] == '.'):
						dist[y + m[1]][x + m[0]] = d + 1
						dq.append((y + m[1], x + m[0], d + 1))
			ans = max(ans, d)
print(ans)


from collections import deque
from copy import deepcopy
(h, w) = map(int, input().split())
s = [list(input()) for i in range(h)]
t = ((0, 1), (1, 0), (-1, 0), (0, -1))
m = 0
for sy in range(h):
	for sx in range(w):
		if s[sy][sx] == '#':
			continue
		ss = deepcopy(s)
		ss[sy][sx] = '#'
		q = deque([(0, sy, sx)])
		max_cost = 0
		(my, mx) = (0, 0)
		while q:
			(cost, y, x) = q.popleft()
			max_cost = max(max_cost, cost)
			cost += 1
			for (i, j) in t:
				ny = y + i
				nx = x + j
				if 0 <= ny < h and 0 <= nx < w:
					if ss[ny][nx] == '.':
						q.append((cost, ny, nx))
						ss[ny][nx] = '#'
		m = max(m, max_cost)
print(m)


import collections
(H, W) = [int(n) for n in input().split()]
MAZE = []
for i in range(H):
	MAZE.append(list(input()))

def bfs(start_x, start_y):
	d = [[-1] * W for i in range(H)]
	dx_dy = [(1, 0), (0, 1), (-1, 0), (0, -1)]
	que = collections.deque([])
	que.append((start_x, start_y))
	d[start_x][start_y] = 0
	cnt = 0
	while que:
		p = que.popleft()
		for (dx, dy) in dx_dy:
			nx = p[0] + dx
			ny = p[1] + dy
			if 0 <= nx < H and 0 <= ny < W and (MAZE[nx][ny] != '#') and (d[nx][ny] == -1):
				que.append((nx, ny))
				d[nx][ny] = d[p[0]][p[1]] + 1
				cnt = max(cnt, d[p[0]][p[1]] + 1)
	return cnt
max_count = 0
for i in range(H):
	for j in range(W):
		if MAZE[i][j] == '#':
			continue
		count = bfs(i, j)
		max_count = max(count, max_count)
print(max_count)


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

def bfs(x, y):
	q = []
	dp = {}

	def qpush(x, y, t):
		if 0 <= x < w and 0 <= y < h and (s[y][x] != '#') and ((x, y) not in dp):
			q.append((x, y))
			dp[x, y] = t
	qpush(x, y, 0)
	while len(q) > 0:
		(x, y) = q.pop(0)
		qpush(x + 1, y, dp[x, y] + 1)
		qpush(x, y - 1, dp[x, y] + 1)
		qpush(x - 1, y, dp[x, y] + 1)
		qpush(x, y + 1, dp[x, y] + 1)
	return dp.get((x, y), 0)
t = 0
for y in range(h):
	for x in range(w):
		t = max(t, bfs(x, y))
print(t)


(n, m) = map(int, input().split())
g = [input() for _ in range(n)]

def bfs(r, c):
	t = [[-1] * m for v in g]
	q = []
	t[r][c] = 0
	q += ((r, c),)
	h = 0
	dirs = [(-1, 0), (0, 1), (1, 0), (0, -1)]
	while h < len(q):
		(r, c) = q[h]
		h += 1
		for d in range(4):
			(r1, c1) = (r + dirs[d][0], c + dirs[d][1])
			if 0 <= r1 < n and 0 <= c1 < m and ('.' == g[r1][c1]) and (t[r1][c1] < 0):
				t[r1][c1] = t[r][c] + 1
				q += ((r1, c1),)
	ret = -1
	for v in t:
		ret = max(ret, max(v))
	return ret
ans = 0
for i in range(n):
	for j in range(m):
		if g[i][j] == '.':
			ans = max(ans, bfs(i, j))
print(ans)


import queue
import numpy as np
(H, W) = list(map(int, input().split()))
maze = [list(input()) for _ in range(H)]
dir4 = [[-1, 0], [1, 0], [0, -1], [0, 1]]

def solveMaze(s):
	q = queue.Queue()
	q.put([s[0], s[1], 0])
	times = [[999999999 for j in range(W)] for i in range(H)]
	tmpAns = 0
	times[s[0]][s[1]] = 0
	while not q.empty():
		now = q.get()
		tmpAns = max(tmpAns, now[2])
		for i in range(4):
			nextH = now[0] + int(dir4[i][0])
			nextW = now[1] + int(dir4[i][1])
			nextTime = now[2] + 1
			if nextH < 0 or nextH >= H or nextW < 0 or (nextW >= W) or (maze[nextH][nextW] == '#') or (times[nextH][nextW] <= nextTime):
				continue
			else:
				times[nextH][nextW] = nextTime
				q.put([nextH, nextW, nextTime])
	return tmpAns
ans = 0
for sH in range(H):
	for sW in range(W):
		if maze[sH][sW] == '.':
			ans = max(ans, solveMaze([sH, sW]))
print(ans)


from collections import deque
(H, W) = map(int, input().split())
m = [list(input()) for i in range(H)]
ans = 0
for h in range(H):
	for w in range(W):
		if m[h][w] == '#':
			continue
		q = deque([(h, w, 0)])
		used = set()
		while q:
			(h, w, c) = q.popleft()
			if (h, w) in used:
				continue
			ans = max(ans, c)
			if 0 <= h - 1 and m[h - 1][w] == '.' and ((h - 1, w) not in used):
				q.append((h - 1, w, c + 1))
			if h + 1 < H and m[h + 1][w] == '.' and ((h + 1, w) not in used):
				q.append((h + 1, w, c + 1))
			if 0 <= w - 1 and m[h][w - 1] == '.' and ((h, w - 1) not in used):
				q.append((h, w - 1, c + 1))
			if w + 1 < W and m[h][w + 1] == '.' and ((h, w + 1) not in used):
				q.append((h, w + 1, c + 1))
			used.add((h, w))
print(ans)


import copy
(H, W) = map(int, input().split())
S = [list(map(str, input())) for _ in range(H)]

def BFS(q):
	flg = copy.deepcopy(S)
	while q != []:
		(cx, cy, cd) = q.pop(0)
		if flg[cx][cy] == '#':
			continue
		else:
			flg[cx][cy] = '#'
		nps = [[cx + 1, cy], [cx - 1, cy], [cx, cy + 1], [cx, cy - 1]]
		for (nx, ny) in nps:
			if 0 <= nx < H and 0 <= ny < W:
				if flg[nx][ny] != '#':
					q.append([nx, ny, cd + 1])
	return cd
ans = 0
for sx in range(H):
	for sy in range(W):
		if S[sx][sy] == '#':
			continue
		else:
			ans = max(ans, BFS([[sx, sy, 0]]))
print(ans)


from collections import deque
(h, w) = map(int, input().split())
s = [input() for _ in range(h)]
ans = 0
for i in range(h):
	for j in range(w):
		if s[i][j] == '#':
			continue
		visited = [[-1] * w for _ in range(h)]
		visited[i][j] = 0
		cnt = 0
		q = deque([[i, j]])
		while q:
			(x, y) = q.popleft()
			for (k, l) in [[0, -1], [0, 1], [1, 0], [-1, 0]]:
				(nx, ny) = (k + x, l + y)
				if nx < 0 or ny < 0 or nx >= h or (ny >= w):
					continue
				if s[nx][ny] == '.' and visited[nx][ny] == -1:
					visited[nx][ny] = visited[x][y] + 1
					q.append([nx, ny])
					ans = max(ans, visited[nx][ny])
print(ans)


from collections import deque
(h, w) = map(int, input().split())
s = [input() for _ in range(h)]
vi = [[-1 for _ in range(w)] for _ in range(h)]
st = deque()
d = [[0, 1], [-1, 0], [1, 0], [0, -1]]
mx = 0
for i in range(h):
	for j in range(w):
		vi = [[-1 for _ in range(w)] for _ in range(h)]
		st.append([i, j, 0])
		while st:
			(h1, w1, k) = st.popleft()
			if 0 <= h1 < h and 0 <= w1 < w and (vi[h1][w1] == -1) and (s[h1][w1] == '.'):
				vi[h1][w1] = k
				for m in d:
					st.append([h1 + m[0], w1 + m[1], k + 1])
		for m in vi:
			mx = max(mx, max(m))
print(mx)


import collections
(H, W) = map(int, input().split())
maze = [[None for _ in range(W)] for _ in range(H)]
for i in range(H):
	maze[i] = list(input())
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
cnt = 0
for j in range(H):
	for k in range(W):
		if maze[j][k] == '#':
			continue
		else:
			sy = j
			sx = k
			seen = [[-1 for _ in range(W)] for _ in range(H)]
			seen[sy][sx] = 0
			que = collections.deque()
			que.append([sy, sx])
			while len(que) != 0:
				p = que.popleft()
				for i in range(4):
					ny = p[0] + dy[i]
					nx = p[1] + dx[i]
					if ny >= 0 and nx >= 0 and (ny < H) and (nx < W) and (seen[ny][nx] == -1) and (maze[ny][nx] != '#'):
						seen[ny][nx] = seen[p[0]][p[1]] + 1
						que.append([ny, nx])
			cnt = max(cnt, max([x for row in seen for x in row]))
print(cnt)


from collections import deque
(H, W) = map(int, input().split())
s = ['#' * (W + 2)] + ['#' + input() + '#' for _ in range(H)] + ['#' * (W + 2)]
(DH, DW) = ([0, 0, 1, -1], [1, -1, 0, 0])

def bfs(start):
	que = deque([start])
	dist = [[-1 for _ in range(W + 2)] for _ in range(H + 2)]
	dist[start[0]][start[1]] = 0
	num = 0
	while que:
		label = que.pop()
		(h, w) = (label[0], label[1])
		for (dh, dw) in zip(DH, DW):
			(hh, ww) = (h + dh, w + dw)
			if s[hh][ww] == '.' and dist[hh][ww] < 0:
				que.appendleft((hh, ww))
				dist[hh][ww] = dist[h][w] + 1
				num = max(num, dist[hh][ww])
	return num
ans = 0
for h in range(1, H + 1):
	for w in range(1, W + 1):
		if s[h][w] == '.':
			ans = max(ans, bfs((h, w)))
print(ans)