### BUGGY CODE ###

H, W = map(int,input().split())
#A = [list(map(str,input().split())) for i in range(H)]
A = [list(input()) for i in range(H)]
#print(A)
from queue import Queue

#q_i = Queue()
#q_j = Queue()

#D = [[401]*W for i in range(H)]
#flag = [[0]*W for i in range(H)]

dj = [1, 0, -1, 0]
di = [0, 1, 0, -1]

fin_d_max = 0

for s_i in range(H):
    for s_j in range(W):
        #print(s_i, s_j, '\n')
        d_max = 0
        q_i = Queue()
        q_j = Queue()
        D = [[401]*W for i in range(H)]
        flag = [[0]*W for i in range(H)]
        #print(sum(D))

        if A[s_i][s_j] == '.':
            D[s_i][s_j] = 0
            q_i.put(s_i)
            q_j.put(s_j)
            while sum(map(sum, flag)) != W*H:
                i = q_i.get()
                j = q_j.get()
                #print(i, j)
                flag[i][j] =1
                for x in range(4):
                    ni = i+di[x]
                    nj = j+dj[x]
                    if ni<0 or ni>=H or nj<0 or nj>=W:
                        continue
                    elif A[ni][nj]== '#' or D[ni][nj] < D[i][j]+1:
                        flag[ni][nj] = 1
                        continue
                    else:
                        D[ni][nj] = D[i][j]+1
                        d_max = max(d_max, D[ni][nj])
                        q_i.put(ni)
                        q_j.put(nj)
                        #print(ni, nj)
                #print(sum(map(sum, flag)))
        #print(D, '\n', '\n')
        #d_max = max(d_max, max(max(D)))
        fin_d_max = max(fin_d_max, d_max)
                
print(fin_d_max)

### FIXED CODE ###

H, W = map(int,input().split())
#A = [list(map(str,input().split())) for i in range(H)]
A = [list(input()) for i in range(H)]

#from queue import Queue
from collections import deque

dj = [1, 0, -1, 0]
di = [0, 1, 0, -1]

sum_sharp = sum([A[i].count('#') for i in range(H)])

fin_d_max = 1

for s_i in range(H):
    for s_j in range(W):
        #print(s_i,s_j)
        d_max = 0
        #q_i = Queue()
        q_i = deque()
        #q_j = Queue()
        q_j = deque()
        D = [[-1]*W for i in range(H)]
        #flag = [[0]*W for i in range(H)]
        flag = 1

        if A[s_i][s_j] == '.':
            D[s_i][s_j] = 0
            #q_i.put(s_i)
            q_i.append(s_i)
            #q_j.put(s_j)
            q_j.append(s_j)
            #while sum(map(sum, flag)) != W*H - sum_sharp:
            #while flag < W*H - sum_sharp:
            #while q_i.empty() == False:
            while len(q_i)!=0:
            #for a in range(W*H):
                #i = q_i.get()
                i = q_i.popleft()
                #j = q_j.get()
                j = q_j.popleft()
                for x in range(4):
                    ni = i+di[x]
                    nj = j+dj[x]
                    #if ni<0 or ni>=H or nj<0 or nj>=W or A[ni][nj]== '#' or 0<=D[ni][nj]<D[i][j]+1:
                    if ni<0 or ni>=H or nj<0 or nj>=W or A[ni][nj]== '#' or D[ni][nj]!=-1:
                    #if ni<0 or ni>=H or nj<0 or nj>=W:
                        continue
                    #elif A[ni][nj]== '#' or D[ni][nj] < D[i][j]+1:
                        #flag[ni][nj] = 1
                        #continue
                    else:
                        #if D[ni][nj] == -1:
                            #print(flag)
                        flag += 1
                        D[ni][nj] = D[i][j]+1
                        d_max = max(d_max, D[ni][nj])
                        #q_i.put(ni)
                        q_i.append(ni)
                        q_j.append(nj)
                        #q_j.put(nj)
        fin_d_max = max(fin_d_max, d_max)
                
print(fin_d_max)