import heapq
import numpy as np

H, W = [int(x) for x in input().split()]
maze = np.zeros((H, W))

for i in range(H):
    for j, way in enumerate(input()):
        if way == '.':
            maze[i, j] = 1
        else:
            maze[i, j] = 0

able_list = []

for i in range(H):
    for j in range(W):
        able = []
        if maze[i,j] == 1:
            if 0 <= i-1 < H:
                if maze[i, j] == 1:
                    able.append([i * W + j, 1])
            if 0 <= j-1 < W:
                if maze[i, j-1] == 1:
                    able.append([i * W + j - 1, 1])
            if 0 <= j+1 < W:
                if maze[i, j+1] == 1:
                    able.append([i* W + j + 1, 1])
            if 0 <= i+1 < H:
                if maze[i+1, j] == 1:
                    able.append([(i+1)*W + j, 1])
        able_list.append(able)



def Dijkstra(list_adjlist, initnode):
    # list_Dを初期化
    list_D = [-1] * len(list_adjlist)
    # 始点の距離=0
    list_D[initnode] = 0
    # list_Tを初期化
    list_T = [-1] * len(list_adjlist)
    # 最短経路・距離が確定している点のリスト
    list_check = [False] * len(list_adjlist)
    # ヒープの初期化：暫定最短距離と点の名前をペアにしたリストをヒープに格納する
    list_S = []
    heapq.heappush(list_S, (list_D[initnode], initnode))
    # ヒープが空になるまで続ける
    while(len(list_S)):
        # ヒープから暫定最短距離が小さい点を取り出す
        pair_w_node = heapq.heappop(list_S)
        if list_check[pair_w_node[1]] is False:
            list_check[pair_w_node[1]] = True
            # 点pair_w_node[1]の各隣接点について調べる
            for neighbor in list_adjlist[pair_w_node[1]]:
                if list_D[neighbor[0]] == -1 or list_D[neighbor[0]] > list_D[pair_w_node[1]] + neighbor[1]:
                    list_D[neighbor[0]] = list_D[pair_w_node[1]] + neighbor[1]
                    list_T[neighbor[0]] = pair_w_node[1]
                    heapq.heappush(list_S, (list_D[neighbor[0]], neighbor[0]))
    return list_D, list_T

ans = 0
for i in range(H):
    for j in range(W):
        if maze[i, j] == 1:
            list_D, list_T = Dijkstra(able_list, i*W + j)
            if ans < max(list_D):
                ans = max(list_D)
print(ans)

### FIXED CODE ###

import heapq
import numpy as np

H, W = [int(x) for x in input().split()]
maze = np.zeros((H, W))

for i in range(H):
    for j, way in enumerate(input()):
        if way == '.':
            maze[i, j] = 1
        else:
            maze[i, j] = 0

able_list = []

for i in range(H):
    for j in range(W):
        able = []
        if maze[i,j] == 1:
            if 0 <= i-1 < H:
                if maze[i-1, j] == 1:
                    able.append([(i-1) * W + j, 1])
            if 0 <= j-1 < W:
                if maze[i, j-1] == 1:
                    able.append([i * W + j - 1, 1])
            if 0 <= j+1 < W:
                if maze[i, j+1] == 1:
                    able.append([i* W + j + 1, 1])
            if 0 <= i+1 < H:
                if maze[i+1, j] == 1:
                    able.append([(i+1)*W + j, 1])
        able_list.append(able)



def Dijkstra(list_adjlist, initnode):
    # list_Dを初期化
    list_D = [-1] * len(list_adjlist)
    # 始点の距離=0
    list_D[initnode] = 0
    # list_Tを初期化
    list_T = [-1] * len(list_adjlist)
    # 最短経路・距離が確定している点のリスト
    list_check = [False] * len(list_adjlist)
    # ヒープの初期化：暫定最短距離と点の名前をペアにしたリストをヒープに格納する
    list_S = []
    heapq.heappush(list_S, (list_D[initnode], initnode))
    # ヒープが空になるまで続ける
    while(len(list_S)):
        # ヒープから暫定最短距離が小さい点を取り出す
        pair_w_node = heapq.heappop(list_S)
        if list_check[pair_w_node[1]] is False:
            list_check[pair_w_node[1]] = True
            # 点pair_w_node[1]の各隣接点について調べる
            for neighbor in list_adjlist[pair_w_node[1]]:
                if list_D[neighbor[0]] == -1 or list_D[neighbor[0]] > list_D[pair_w_node[1]] + neighbor[1]:
                    list_D[neighbor[0]] = list_D[pair_w_node[1]] + neighbor[1]
                    list_T[neighbor[0]] = pair_w_node[1]
                    heapq.heappush(list_S, (list_D[neighbor[0]], neighbor[0]))
    return list_D, list_T

ans = 0
for i in range(H):
    for j in range(W):
        if maze[i, j] == 1:
            list_D, list_T = Dijkstra(able_list, i*W + j)
            if ans < max(list_D):
                ans = max(list_D)
print(ans)