import sys,copy

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def IS(): return sys.stdin.readline()
def II(): return int(sys.stdin.readline())
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LI1(): return list(map(int1, sys.stdin.readline().split()))
def LII(rows_number): return [II() for _ in range(rows_number)]
def LLI(rows_number): return [LI() for _ in range(rows_number)]
def LLI1(rows_number): return [LI1() for _ in range(rows_number)]

def main():
	H,W = MI()
	maze = [[0 for _ in range(W)] for _ in range(H)]
	for i in range(H):
		S = IS()
		for j,s in enumerate(S):
			if s == '#':
				maze[i][j] = -1
	
	def bfs(sx,sy):
		from collections import deque
		que = deque()
		dist_map = copy.deepcopy(maze)
		que.append((sx,sy, dist_map[sy][sx]))
		while len(que) > 0:
			x,y,d=que.popleft()
			dist_map[y][x] = d
			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):
					if(dist_map[ny][nx]==0):
						que.append((nx,ny,d+1))
		return d

	ans = -1
	for i in range(H):
		for j in range(W):
			if(maze[i][j]==0):
				dist = bfs(j,i)
				if(dist > ans):
					ans = dist
	print(ans)

main()