from heapq import heappop,heappush



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

s = [[x for x in eval(input())] for _ in range(h)]



delta = [(-1,0),(1,0),(0,1),(0,-1)]



edges = [[-1 for _ in range(h*w)] for __ in range(h*w)]



for i in range(h):

    for j in range(w):

        if s[i][j] == '.':

            for x in delta:

                to_i = i+x[0]

                to_j = j+x[1]

                if 0 <= to_i < h and 0 <= to_j < w:

                    if s[to_i][to_j] == '.':

                        edges[i*w+j][to_i*w+to_j] = 1

                        edges[to_i*w+to_j][i*w+j] = 1



n = h*w



def dijkstra(s,n,edges):

    #edges[i][j] : the cost of i→j

    #import 'heap'

    d = [10**13] * n

    d[s] = 0

    q = [(0,s)]

    while q:

        dist_u, u = heappop(q)

        if d[u] < dist_u:

            continue

        for v, c in enumerate(edges[u]):

            if c >= 0:

                if d[v] > dist_u + c:

                    d[v] = dist_u + c

                    heappush(q, (d[v], v))

    return d



ans = 0



for i in range(h):

    for j in range(w):

        d = dijkstra(i*w+j,n,edges)

        for l in d:

            if l < 10**6:

                ans = max(ans,l)



print(ans)

from collections import deque





def solve(S, s):

    if S[s[0]][s[1]] != ".":

        return -1

    queue = deque([s])

    visited = [[-1 for _ in range(W)] for _ in range(H)]

    visited[s[0]][s[1]] = 0

    while queue:

        y, x = queue.popleft()

        for j, k in ([1,0], [-1,0], [0,1], [0,-1]):

            new_y, new_x = y+j, x+k

            if new_x in range(W) and new_y in range(H) and S[new_y][new_x] == "." and visited[new_y][new_x] == -1:

                visited[new_y][new_x] = visited[y][x] + 1

                queue.append([new_y, new_x])

#    for v in visited:

#        print(v)

    return max(list(map(max,visited)))





H, W = list(map(int, input().split()))

S = [eval(input()) for _ in range(H)]

ans = -1

for i in range(H):

    for l in range(W):

        ans = max(ans, solve(S, [i, l]))

print(ans)

from heapq import heappop, heappush

h, w = list(map(int, input().split()))
s = [[x for x in eval(input())] for _ in range(h)]
delta = [(-1, 0), (1, 0), (0, 1), (0, -1)]
edges = [[-1 for _ in range(h * w)] for __ in range(h * w)]
for i in range(h):
    for j in range(w):
        if s[i][j] == ".":
            for x in delta:
                to_i = i + x[0]
                to_j = j + x[1]
                if 0 <= to_i < h and 0 <= to_j < w:
                    if s[to_i][to_j] == ".":
                        edges[i * w + j][to_i * w + to_j] = 1
                        edges[to_i * w + to_j][i * w + j] = 1
n = h * w


def dijkstra(s, n, edges):
    # edges[i][j] : the cost of i→j
    # import 'heap'
    d = [10**13] * n
    d[s] = 0
    q = [(0, s)]
    while q:
        dist_u, u = heappop(q)
        if d[u] < dist_u:
            continue
        for v, c in enumerate(edges[u]):
            if c >= 0:
                if d[v] > dist_u + c:
                    d[v] = dist_u + c
                    heappush(q, (d[v], v))
    return d


ans = 0
for i in range(h):
    for j in range(w):
        d = dijkstra(i * w + j, n, edges)
        for l in d:
            if l < 10**6:
                ans = max(ans, l)
print(ans)

from collections import deque


def solve(S, s):
    if S[s[0]][s[1]] != ".":
        return -1
    queue = deque([s])
    visited = [[-1 for _ in range(W)] for _ in range(H)]
    visited[s[0]][s[1]] = 0
    while queue:
        y, x = queue.popleft()
        for j, k in ([1, 0], [-1, 0], [0, 1], [0, -1]):
            new_y, new_x = y + j, x + k
            if (
                new_x in range(W)
                and new_y in range(H)
                and S[new_y][new_x] == "."
                and visited[new_y][new_x] == -1
            ):
                visited[new_y][new_x] = visited[y][x] + 1
                queue.append([new_y, new_x])
    #    for v in visited:
    #        print(v)
    return max(list(map(max, visited)))


H, W = list(map(int, input().split()))
S = [eval(input()) for _ in range(H)]
ans = -1
for i in range(H):
    for l in range(W):
        ans = max(ans, solve(S, [i, l]))
print(ans)

-from heapq import heappop, heappush - -h, w = list(map(int, input().split())) -s = [[x for x in eval(input())] for _ in range(h)] -delta = [(-1, 0), (1, 0), (0, 1), (0, -1)] -edges = [[-1 for _ in range(h * w)] for __ in range(h * w)] -for i in range(h): -    for j in range(w): -        if s[i][j] == ".": -            for x in delta: -                to_i = i + x[0] -                to_j = j + x[1] -                if 0 <= to_i < h and 0 <= to_j < w: -                    if s[to_i][to_j] == ".": -                        edges[i * w + j][to_i * w + to_j] = 1 -                        edges[to_i * w + to_j][i * w + j] = 1 -n = h * w +from collections import deque -def dijkstra(s, n, edges): -    # edges[i][j] : the cost of i→j -    # import 'heap' -    d = [10**13] * n -    d[s] = 0 -    q = [(0, s)] -    while q: -        dist_u, u = heappop(q) -        if d[u] < dist_u: -            continue -        for v, c in enumerate(edges[u]): -            if c >= 0: -                if d[v] > dist_u + c: -                    d[v] = dist_u + c -                    heappush(q, (d[v], v)) -    return d +def solve(S, s): +    if S[s[0]][s[1]] != ".": +        return -1 +    queue = deque([s]) +    visited = [[-1 for _ in range(W)] for _ in range(H)] +    visited[s[0]][s[1]] = 0 +    while queue: +        y, x = queue.popleft() +        for j, k in ([1, 0], [-1, 0], [0, 1], [0, -1]): +            new_y, new_x = y + j, x + k +            if ( +                new_x in range(W) +                and new_y in range(H) +                and S[new_y][new_x] == "." +                and visited[new_y][new_x] == -1 +            ): +                visited[new_y][new_x] = visited[y][x] + 1 +                queue.append([new_y, new_x]) +    #    for v in visited: +    #        print(v) +    return max(list(map(max, visited))) -ans = 0 -for i in range(h): -    for j in range(w): -        d = dijkstra(i * w + j, n, edges) -        for l in d: -            if l < 10**6: -                ans = max(ans, l) +H, W = list(map(int, input().split())) +S = [eval(input()) for _ in range(H)] +ans = -1 +for i in range(H): +    for l in range(W): +        ans = max(ans, solve(S, [i, l]))