#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
f = open('input.txt', 'r')
sys.stdin = f
input = sys.stdin.readline
# 3.24の練習


# D maze master

h, w = map(int, input().split())

graph = {i: {} for i in range(1, h * w + 1)}

data = []
data.append([False for i in range(w + 2)])
for i in range(h):
    s = list(input())
    sub = [False]
    for i in range(w):
        if s[i] is "#":
            sub.append(False)
        else:
            sub.append(True)
    sub.append(False)
    data.append(sub)
data.append([False for i in range(2 + w)])

for i in range(1, h + 1):
    for j in range(1, w + 1):
        # now data[i][j]
        if data[i][j]:
            now = w * (i - 1) + j
            if data[i - 1][j]:
                node = w * (i - 1) + j
                graph[now][node]=1
                graph[node][now]=1
            if data[i][j + 1]:
                node = w* (i - 1) + j + 1
                graph[now][node]=1
                graph[node][now]=1
            if data[i][j - 1]:
                node = w * (i - 1) + j - 1
                graph[node][now]=1
                graph[now][node]=1
            if data[i + 1][j]:
                node = w * i + j
                graph[node][now]=1
                graph[now][node]=1

# graph=迷路のグラフデータ構造

import heapq
def dijkstra(s,graph,n):
    #ｓからのグラフの最短最短距離をまとめたデータを返す
    dist=[10**20 for i in range(n+1)]
    dist[s]=0
    pq=[]
    heapq.heapify(pq)
    #全ての接点を一度優先度付きキューに挿入する
    heapq.heappush(pq,(0,s))
    while pq:
        x=heapq.heappop(pq)
        node,mini_dis=x[1],x[0]
        for point in graph[node].keys():
            w=graph[node][point]
            #nodeからpointに対して伸びる辺の長さ
            newlen=dist[node]+w
            if newlen<dist[point]:
                heapq.heappush(pq,(newlen,point))
                dist[point]=newlen
    mea=0
    for i in range(1,n+1):
        if 0<dist[i]<10**20:
            mea=max(dist[i],mea)
    return mea

###############################################################
ans=0
for i in range(1,h*w+1):
    if graph[i]:
        ans=max(ans,dijkstra(i,graph,h*w))
print(ans)


### FIXED CODE ###

h,w=map(int,input().split())
field=[]
field.append([True for i in range(w+2)])
start=[]
for i  in range(h):
    s=input()
    sub=[True]
    for j in range(w):
        if s[j]=="#":
            sub.append(True)
        else:
            sub.append(False)
            start.append((i+1,j+1))
    
    sub.append(True)
    field.append(sub)

            
        
    
field.append([True for i in range(w+2)])

from collections import deque
import copy
dis=[]
for i in range(len(start)):

        fields=copy.deepcopy(field)
        d=deque()
        e=deque()
        distance=0
        fields[start[i][0]][start[i][1]]=True

        d.append((start[i][0],start[i][1]))
        while d:
            for some in d:
                index1,index2=some[0],some[1]
                if fields[index1-1][index2]==False:
                    fields[index1-1][index2]=True
                    e.append((index1-1,index2))
                if fields[index1+1][index2]==False:
                    fields[index1+1][index2]=True
                    e.append((index1+1,index2))
                if fields[index1][index2+1]==False:
                    fields[index1][index2+1]=True
                    e.append((index1,index2+1))
                if  fields[index1][index2-1]==False:
                    fields[index1][index2-1]=True
                    e.append((index1,index2-1))
            distance+=1
            d=e
            e=deque()

        dis.append(distance)
    


print(max(dis)  -1)