import queue

h,w = map(int,input().split())
maze = []

for i in range(h):
	mazeRow = list(input())
	maze.append(mazeRow)
	
maxRootCnt = 0

#スタート→ゴール全探索（ま？）
for roop_h in range(h):
	for roop_w in range(w):
		if maze[roop_h][roop_w] == '#':
			continue

		isSearched =  [[0] * w for i in range(h)]
		isLevel =  [[0] * w for i in range(h)]
		nowTansakuCnt = 0

		q = queue.Queue()
		q.put([roop_h,roop_w])

		# 探索済マスセット
		isSearched[roop_h][roop_w] = 1
		isLevel[roop_h][roop_w] = 0
		while not q.empty():
			n= q.get()
			nowLevel = isLevel[n[0]][n[1]]
			if nowLevel > maxRootCnt:
				maxRootCnt = nowLevel
			#北
			if n[0] != 0:
				if maze[n[0] -1][n[1]] == '.' and isSearched[n[0] -1][n[1]] == 0:
					q.put([n[0]-1,n[1]])
					isSearched[n[0] -1][n[1]] = 1
					isLevel[n[0] -1][n[1]] = nowLevel + 1
			#南
			if n[0] != h-1:
				if maze[n[0] +1][n[1]] == '.' and isSearched[n[0]+-1][n[1]] == 0:
					q.put([n[0]+1,n[1]])
					isSearched[n[0] +1][n[1]] = 1
					isLevel[n[0] +1][n[1]] = nowLevel + 1
				
			#西
			if n[1] != 0:
				if maze[n[0]][n[1]-1] == '.' and isSearched[n[0]][n[1]-1] == 0:
					q.put([n[0],n[1]-1])
					isSearched[n[0]][n[1]-1] = 1
					isLevel[n[0]][n[1]-1] = nowLevel + 1

			#東            
			if n[1] != w-1:
				if maze[n[0]][n[1]+1] == '.' and isSearched[n[0]][n[1]+1] == 0:
					q.put([n[0],n[1]+1])
					isSearched[n[0]][n[1]+1] = 1
					isLevel[n[0]][n[1]+1] = nowLevel + 1
				                    
print(maxRootCnt)
