import numpy as np
inp = input()
H,W = inp.split()
H,W = int(H), int(W)

HW = H* W
adj = np.zeros((HW,HW), dtype = np.int8)
mapp = np.zeros((H,W), dtype = np.int8)

dr = [-1, +1,  0,  0]
dc = [ 0,  0, +1, -1]


for r in range(H):
    inp = input()
    for c in range(len(inp)):
        if inp[c] == '.':
            mapp[r,c] = 0
        else:
            mapp[r,c] = 1

            
#             adj[rr,cc] = 1
def minimum_steps(sr, sc, er, ec):    
    rq, cq = [], []
    visited = np.zeros((H,W), dtype = np.int8)
    move_count = 0
    nodes_left_in_layer = 1
    nodes_in_next_layer = 0
    
    reached = False
    
    
    rq.append(sr)
    cq.append(sc)
    visited[sr,sc] = 1
    
    while len(rq)>0:
        #print(rq, cq)
        r,c = rq[0], cq[0]
        rq.pop(0)
        cq.pop(0)
        
        if (r,c) == (er,ec):
            reached = True
            break

        #explore negiht
        for i in range(4):
            rr = r+dr[i]
            cc = c+dc[i]
            if rr < 0 or cc <0:
                continue
            elif rr >= H or cc >=W:
                continue

            if visited[rr][cc]:
                continue
            if mapp[r,c] == 1:
                continue
            rq.append(rr) 
            cq.append(cc)
            visited[rr][cc] = 1
            nodes_in_next_layer +=1
        #explore neihgbors
        
        nodes_left_in_layer-=1
        if nodes_left_in_layer == 0:
            nodes_left_in_layer = nodes_in_next_layer
            nodes_in_next_layer = 0
            move_count+=1
    if reached:
        return move_count
    return -1

maxValue = 0
for sr in np.arange(H, dtype= np.int8):
    for sc in np.arange(W, dtype= np.int8):
        for er in np.arange(H, dtype= np.int8):
            for ec in np.arange(W, dtype= np.int8):
                if maxValue < minimum_steps(sr, sc, er, ec):
                    maxValue = minimum_steps(sr, sc, er, ec)
print(maxValue)