import sys

sys.setrecursionlimit(10**7)
INF = 10 ** 18
MOD = 10 ** 9 + 7
def LI(): return list(map(int, sys.stdin.readline().split()))
def II(): return int(sys.stdin.readline())
def LS(): return list(map(list, sys.stdin.readline().split()))
def S(): return list(sys.stdin.readline())[:-1]

from collections import deque, defaultdict

def dfs(s, t, n, g):
    Q = deque([s])
    searched = [0 for i in range(n)]
    searched[s] = 1
    depth = [0 for i in range(n)]
    while len(Q) != 0:
        v = Q.popleft()
        for i in g[v]:
            if i == t:
                depth[i] = depth[v] + 1
                # print(depth[i], s, t)
                return depth[i]
            if searched[i] == 0:
                depth[i] = depth[v] + 1
                Q.append(i)
                searched[i] = 1
    # print(searched[:16])



def main():
    h, w = LI()
    g = defaultdict(list)
    old_s = ["#" for _ in range(w)]
    dames = set()
    for i in range(h):
        s = S()
        # print(s)
        for j in range(w):
            if s[j] == "#":
                dames.add(i * w + j)
                continue
            if old_s[j] != "#":
                g[i * w + j].append(i * w + j - w)
                g[i * w + j - w].append(i * w + j)
            if j != w - 1 and s[j+1] != "#":
                g[i * w + j].append(i * w + j + 1)
                g[i * w + j + 1].append(i * w + j)
        old_s = s
    if h > 2:
        cands = [i for i in range(w)] + [w*i for i in range(1, h - 1)] + [w*(i+i)-1 for i in range(1, h - 1)] + [i+w*(h-1) for i in range(w)]
    else:
        cands = [0]
    min_ = 0
    print(g)
    cands = [i for i in cands if i not in dames]
    for i in cands:
        for j in cands:
            if i > j:
                d = dfs(i, j, 500, g)
                min_ = max(min_, d)

    print(min_)


if __name__ == '__main__':
    main()