#!/usr/bin/env python3
#abc151_d
import sys
from collections import deque
mv = ((1,0),(-1,0),(0,1),(0,-1))
h,w = map(int,input().split())
board = [["#"]*(w+2) for _ in range(h+2)]
for i in range(h):
    s = input()
    for j in range(w):
        board[i+1][j+1] = str(s[j])
cur_max = 0 # 初期点を変更しながら全探索した時のmax
#print(board[0][0] == ".")
for i in range(h+2):
    for j in range(w+2):
        #print(i,j,board[i][j])
        tmp =  board[i][j]
        if tmp == ".":
            visit = deque()
            start_pos = (i,j)
            visit.append(start_pos)
            cnt = [[-1]*(w+2) for _ in range(h+2)] # -1埋め
            cnt[i][j] = 0 #スタート地点は0
            while visit:
                point = visit.popleft()
                for i in mv:
                    pos = point + i
                    if str(board[pos[0]][pos[1]]) == ".":
                        if cnt[pos[0]][pos[1]] == -1: #unvisited
                            cnt[pos[0]][pos[1]] = cnt[point[0]][point[1]] + 1
                            if cnt[pos[0]][pos[1]] > cur_max:
                                cur_max = cnt[pos[0]][pos[1]]
print(cur_max)                    

"""



# 既に訪れたかどうかを確かめるため、最短経路パスを保存するためにh+2*w+2の２次元配列を用意する
for i in range(h+2):
	for j in range(w+2):
		if i*(i-h-2) == 0 or j*(j-w-2) == 0 or s[i-1][j-1] == "#":
			#ここは通れない地点なのでdist = -1にする
			dist[i][j] = -1
        else: 
            dist[i][j] = 0
# スタートにできる全ての地点に対してループを回す
ans = 0
for i in range(h+2):
    for j in range(w+2):
        if dist[i][j] == 0:
            q = deque()
            start_pos = (i,j)
            q.append(start_pos)
            max_ = 0
            while len(q) > 0:
                pos = q.popleft()
                for i in range(4):
                    next_pos = (pos[0]+mv[i][0],pos[1]+mv[i][1])
                    if dist[next_pos[0]][next_pos[1]] == 0:
                        dist[next_pos[0]][next_pos[1]] = dist[pos[0]][pos[1]] + 1 
                        q.append(next_pos)
                        max_ = max(max_,dist[next_pos[0]][next_pos[1]])
            ans = max(max_,ans)
print(ans)"""

### FIXED CODE ###

#!/usr/bin/env python3
#abc151_d
import sys
from collections import deque
mv = ((1,0),(-1,0),(0,1),(0,-1))
h,w = map(int,input().split())
board = [["#"]*(w+2) for _ in range(h+2)]
for i in range(h):
    s = input()
    for j in range(w):
        board[i+1][j+1] = str(s[j])
cur_max = 0 # 初期点を変更しながら全探索した時のmax
#print(board[0][0] == ".")
#for i in range(h+2):
    #print(board[i])
for i in range(h+2):
    for j in range(w+2):
        #print(i,j,board[i][j])
        tmp =  board[i][j]
        if tmp == ".":
            #print("yes",i,j)
            visit = deque()
            start_pos = (i,j)
            visit.append(start_pos)
            cnt = [[-1]*(w+2) for _ in range(h+2)] # -1埋め
            cnt[i][j] = 0 #スタート地点は0
            while visit:
                point = visit.popleft()
                #print(point[0], point[1])
                for k in mv:
                    pos = (point[0]+k[0],point[1]+k[1])
                    #print(pos)
                    if str(board[pos[0]][pos[1]]) == ".":
                        if cnt[pos[0]][pos[1]] == -1: #unvisited
                            #print(i,j,"yes")
                            cnt[pos[0]][pos[1]] = cnt[point[0]][point[1]] + 1
                            visit.append((pos[0],pos[1]))
                            if cnt[pos[0]][pos[1]] > cur_max:
                                cur_max = cnt[pos[0]][pos[1]]
print(cur_max)