### BUGGY CODE ###

import queue

max = 0

tmp = []
tmp = list(map(int, input().split()))

w = tmp.pop()
h = tmp.pop()

maze = [["." for i in range(w)] for j in range(h)]
flag = [[False for i in range(w)] for j in range(h)]

for i in range(h):
    maze[i] = list(input())

xq = queue.Queue()
yq = queue.Queue()
lq = queue.Queue()
    
for i in range(w):
    for j in range(h):

        flag = [[False for i in range(w)] for j in range(h)]
        #        print("{} {} {}".format(j,i, maze[j][i]))
        # start をqueueにいれる
        if maze[j][i]==".":
            xq.put(i)
            yq.put(j)
            lq.put(0)
            flag[j][i]=True

        while not xq.empty():
            x = xq.get() #現在地 x
            y = yq.get() #現在地 y
            l = lq.get() #距離 l

            if max < l:
                max = l
            

            #行ける方向をチェックしてqueueにつむ、訪問済みにする
            #行ける方向 = 上下左右隣接、
            # なおかつ、壁じゃない、迷路の外じゃない、すでに訪問済みじゃない

            # チェックするのは4方向
            if ((x-1) >= 0 ):
                if (flag[y][x-1]==False) and (maze[y][x-1])==".":
                    xq.put(x-1)
                    yq.put(y)
                    lq.put(l+1)
                    flag[y][x-1]=True
                
            if ((x+1) < w ):
#                print("{} {} {}".format(x, y, l))
#                print(maze[x][y])
                if flag[y][x+1]==False and maze[y][x+1]==".":
                    xq.put(x+1)
                    yq.put(y)
                    lq.put(l+1)
                    flag[y][x+1]=True
                
            if ((y-1) >= 0):
                if flag[y-1][x]==False and maze[y-1][x]==".":
                    xq.put(x)
                    yq.put(y-1)
                    lq.put(l+1)
                    flag[y-1][x]=True

            if ((y+1) < h):
#                print("{} {} {}".format(x, y, l))
#                print(maze[x][y])
                if flag[y+1][x]==False and maze[y+1][x]==".":
                    xq.put(x)
                    yq.put(y+1)
                    lq.put(l+1)
                    flag[y+1][x]=True
                

print(max)

### FIXED CODE ###

from collections import deque

max = 0

tmp = []
tmp = list(map(int, input().split()))

w = tmp.pop()
h = tmp.pop()

maze = [["." for i in range(w)] for j in range(h)]

for i in range(h):
    maze[i] = list(input())

xq = deque()
yq = deque()
lq = deque()
    
for i in range(w):
    for j in range(h):

        flag = [[False for i in range(w)] for j in range(h)]
        #        print("{} {} {}".format(j,i, maze[j][i]))
        # start が壁でなければqueueにいれる
        if maze[j][i]==".":
            xq.appendleft(i)
            yq.appendleft(j)
            lq.appendleft(0)
            flag[j][i]=True

        while not len(xq)==0:
            x = xq.pop() #現在地 x
            y = yq.pop() #現在地 y
            l = lq.pop() #距離 l

            if max < l:
                max = l
            
            #行ける方向をチェックしてqueueにつむ、訪問済みにする
            #行ける方向 = 上下左右隣接、
            # なおかつ、壁じゃない、迷路の外じゃない、すでに訪問済みじゃない

            # チェックするのは4方向
            if ((x-1) >= 0 ):
                if (flag[y][x-1]==False) and (maze[y][x-1])==".":
                    xq.appendleft(x-1)
                    yq.appendleft(y)
                    lq.appendleft(l+1)
                    flag[y][x-1]=True
                
            if ((x+1) < w ):
#                print("{} {} {}".format(x, y, l))
#                print(maze[x][y])
                if flag[y][x+1]==False and maze[y][x+1]==".":
                    xq.appendleft(x+1)
                    yq.appendleft(y)
                    lq.appendleft(l+1)
                    flag[y][x+1]=True
                
            if ((y-1) >= 0):
                if flag[y-1][x]==False and maze[y-1][x]==".":
                    xq.appendleft(x)
                    yq.appendleft(y-1)
                    lq.appendleft(l+1)
                    flag[y-1][x]=True

            if ((y+1) < h):
#                print("{} {} {}".format(x, y, l))
#                print(maze[x][y])
                if flag[y+1][x]==False and maze[y+1][x]==".":
                    xq.appendleft(x)
                    yq.appendleft(y+1)
                    lq.appendleft(l+1)
                    flag[y+1][x]=True
                

print(max)