class Maze():
    def __init__(self, H, W, road='.', wall='#'):
        self.H=H
        self.W=W
        self.road='.'
        self.wall='#'
        self.S=[]
    
    def __len__(self):
        return len(self.S)

    def __getitem__(self, index):
        return self.S[index]

    def get(self,i,j):
        if len(self.S)!=self.H*self.W:
            raise ValueError('Maze is not ready')

        if i<0 or i>=self.H or j<0 or j>=self.W:
            return ''
        else:
            return self.S[self.W*i + j]

    def add_row(self,Si):
        if len(Si) != self.W:
            raise ValueError
        self.S.extend(Si)

    def get_adjacent(self, index):
        out = []
        i, j = self._index_to_ij(index)
        if self.get(i-1,j)!='':
            out.append(tuple([self._ij_to_index(i-1,j), self.get(i-1,j)]))
        if self.get(i+1,j)!='':
            out.append(tuple([self._ij_to_index(i+1,j), self.get(i+1,j)]))
        if self.get(i,j-1)!='':
            out.append(tuple([self._ij_to_index(i,j-1), self.get(i,j-1)]))
        if self.get(i,j+1)!='':
            out.append(tuple([self._ij_to_index(i,j+1), self.get(i,j+1)]))
        return out

    def _index_to_ij(self, index):
        i = index // self.W
        j = index % self.W
        return i, j

    def _ij_to_index(self, i, j):
        return self.W*i + j
      

def maze_to_graph(maze):
    G = []
    for node_index in range(len(maze)):
        Gi = []
        if maze[node_index]=='#':
            out = []
        else:
            out = maze.get_adjacent(node_index)
       
        for index, mark in out:
            if mark=='#':
                pass
            elif mark=='.':
                Gi.append(index)
        G.append(tuple(Gi))

    return G
  
  
from collections import deque

def bfs(G, init):
    seen = [False for i in range(len(G))]
    todo = deque()
    todo.append(init)

    dist = [-1 for i in range(len(G))]
    dist[init] = 0

    while todo:
        node_index = todo.popleft()
        seen[node_index] = True
        if dist[node_index]==-1:
            raise ValueError
        for i in G[node_index]:
            if seen[i] == True:
                pass
            else:
                todo.append(i)
                if dist[i]==-1:
                    dist[i]=dist[node_index]+1

    return dist
  
H, W = map(int, input().split())
input_maze = []
for i in range(H):
    input_maze.append(input())
maze = Maze(H,W)
for Si in input_maze:
    maze.add_row(Si)

G = maze_to_graph(maze)
dists = []
for i in range(len(G)):
    dists.append(max(bfs(G, i)))

print(max(dists))