import sys
input=sys.stdin.readline
sys.setrecursionlimit(10 ** 6)
from collections import defaultdict
import fractions
import math
from collections import deque
from bisect import bisect_left
from bisect import insort_left
import itertools
from heapq import heapify
from heapq import heappop
from heapq import heappush
import numpy as np
INF = float("inf")
#d = defaultdict(int)
#N = int(input())
#A = list(map(int,input().split()))
#S = list(input())
#S.remove("\n")
#N,M = map(int,input().split())
#S,T = map(str,input().split())
#A = [int(input()) for _ in range(N)]
#S = [input() for _ in range(N)]
#A = [list(map(int,input().split())) for _ in range(N)]
cmd = [[-1,0],[1,0],[0,1],[0,-1]]
h,w = map(int,input().split())
Map = [["#"]*(w+2)]
for _ in range(h):
    s = ["#"]+list(input())[:-1]+["#"]
    Map.append(s)
Map.append(["#"]*(w+2))
MAX = 0
for sx in range(1,w+1):
    for sy in range(1,h+1):
        for gx in range(1,w+1):
            for gy in range(1,h+1):
                p = -1
                if Map[sy][sx] == "#" or Map[gy][gx] == "#":
                    continue
                q = deque([[sx,sy]])
                visidat = [[0]*(w+2) for _ in range(h+2)]
                while len(q) != 0:
                    x,y = q.popleft()
                    for cx,cy in cmd:
                        newx = x + cx
                        newy = y + cy
                        if Map[newy][newx] == "#":
                            continue
                        else:
                            if visidat[newy][newx] == 0:
                                visidat[newy][newx] += visidat[y][x] + 1
                                q.append([newx,newy])
                            if newx == gx and newy == gy:
                                p = visidat[newy][newx]
                MAX = max(MAX,p)
print(MAX)

### FIXED CODE ###

import sys
input=sys.stdin.readline
sys.setrecursionlimit(10 ** 6)
from collections import defaultdict
import fractions
import math
from collections import deque
from bisect import bisect_left
from bisect import insort_left
import itertools
from heapq import heapify
from heapq import heappop
from heapq import heappush
import numpy as np
INF = float("inf")
#d = defaultdict(int)
#N = int(input())
#A = list(map(int,input().split()))
#S = list(input())
#S.remove("\n")
#N,M = map(int,input().split())
#S,T = map(str,input().split())
#A = [int(input()) for _ in range(N)]
#S = [input() for _ in range(N)]
#A = [list(map(int,input().split())) for _ in range(N)]
cmd = [[-1,0],[1,0],[0,1],[0,-1]]
h,w = map(int,input().split())
Map = [["#"]*(w+2)]
for _ in range(h):
    s = ["#"]+list(input())[:-1]+["#"]
    Map.append(s)
Map.append(["#"]*(w+2))
MAX = 0
for sx in range(1,w+1):
    for sy in range(1,h+1):
        p = 0
        if Map[sy][sx] == "#":
            continue
        q = deque([[sx,sy]])
        visidat = [[0]*(w+2) for _ in range(h+2)]
        while len(q) != 0:
            x,y = q.popleft()
            for cx,cy in cmd:
                newx = x + cx
                newy = y + cy
                if Map[newy][newx] == "#" or(newx ==sx and newy == sy):
                    continue
                else: 
                    if visidat[newy][newx] == 0:
                        visidat[newy][newx] += visidat[y][x] + 1
                        if p < visidat[newy][newx]:
                            p = visidat[newy][newx]
                        q.append([newx,newy])
        MAX = max(MAX,p)
print(MAX)