import sys

sys.setrecursionlimit(10**6)



def main():

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



    S = ["" for _ in range(H)]

    for i in range(H):

        S[i] = eval(input())



    INF = float("inf")

    N = H*W

    dp = [[INF for _ in range(N)] for _ in range(N)]



    for i in range(H):

        for j in range(W):

            

            if j != W-1 and S[i][j] == "." and S[i][j+1] == ".":

                dp[(W*i)+j][(W*i)+j+1] = 1

                dp[(W*i)+j+1][(W*i)+j] = 1



            if i != H-1 and S[i][j] == "." and S[i+1][j] == ".":



                dp[(W*i)+j][(W*(i+1))+j] = 1

                dp[(W*(i+1))+j][(W*i)+j] = 1

        

            dp[(W*i)+j][(W*i)+j] = 0





    N = H*W

    for k in range(N):

        for i in range(N):

            for j in range(N):

                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j])



    ans = 0

    for i in range(N):

        for j in range(N):

            if dp[i][j] != INF:

                ans = max(ans, dp[i][j])

    

    print(ans)



if __name__ == "__main__":

    main()
from collections import deque







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

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



ans = 0

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

for i in range(H):

    for j in range(W):

        if S[i][j] == "#": continue

        dist = [[0 for _ in range(W)] for _ in range(H)] 

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

        visited[i][j] = True

        q = deque()

        q.append((i,j))

        while q:

            y,x = q.popleft()

            for dy,dx in dyx:

                ny, nx = y+dy, x+dx

                if not 0 <= ny <= H-1 or not 0 <= nx <= W-1 or visited[ny][nx] == True or S[ny][nx] == "#":

                    continue

                q.append((ny, nx))

                dist[ny][nx] = dist[y][x] + 1

                visited[ny][nx] = True







        ans = max(ans, max(max(row) for row in dist))



            



print(ans)
import sys

sys.setrecursionlimit(10**6)


def main():
    H, W = list(map(int, input().split()))
    S = ["" for _ in range(H)]
    for i in range(H):
        S[i] = eval(input())
    INF = float("inf")
    N = H * W
    dp = [[INF for _ in range(N)] for _ in range(N)]
    for i in range(H):
        for j in range(W):
            if j != W - 1 and S[i][j] == "." and S[i][j + 1] == ".":
                dp[(W * i) + j][(W * i) + j + 1] = 1
                dp[(W * i) + j + 1][(W * i) + j] = 1
            if i != H - 1 and S[i][j] == "." and S[i + 1][j] == ".":
                dp[(W * i) + j][(W * (i + 1)) + j] = 1
                dp[(W * (i + 1)) + j][(W * i) + j] = 1
            dp[(W * i) + j][(W * i) + j] = 0
    N = H * W
    for k in range(N):
        for i in range(N):
            for j in range(N):
                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j])
    ans = 0
    for i in range(N):
        for j in range(N):
            if dp[i][j] != INF:
                ans = max(ans, dp[i][j])
    print(ans)


if __name__ == "__main__":
    main()

from collections import deque

H, W = list(map(int, input().split()))
S = [eval(input()) for _ in range(H)]
ans = 0
dyx = [(1, 0), (0, 1), (-1, 0), (0, -1)]
for i in range(H):
    for j in range(W):
        if S[i][j] == "#":
            continue
        dist = [[0 for _ in range(W)] for _ in range(H)]
        visited = [[False for _ in range(W)] for _ in range(H)]
        visited[i][j] = True
        q = deque()
        q.append((i, j))
        while q:
            y, x = q.popleft()
            for dy, dx in dyx:
                ny, nx = y + dy, x + dx
                if (
                    not 0 <= ny <= H - 1
                    or not 0 <= nx <= W - 1
                    or visited[ny][nx] == True
                    or S[ny][nx] == "#"
                ):
                    continue
                q.append((ny, nx))
                dist[ny][nx] = dist[y][x] + 1
                visited[ny][nx] = True
        ans = max(ans, max(max(row) for row in dist))
print(ans)

-import sys +from collections import deque -sys.setrecursionlimit(10**6) - - -def main(): -    H, W = list(map(int, input().split())) -    S = ["" for _ in range(H)] -    for i in range(H): -        S[i] = eval(input()) -    INF = float("inf") -    N = H * W -    dp = [[INF for _ in range(N)] for _ in range(N)] -    for i in range(H): -        for j in range(W): -            if j != W - 1 and S[i][j] == "." and S[i][j + 1] == ".": -                dp[(W * i) + j][(W * i) + j + 1] = 1 -                dp[(W * i) + j + 1][(W * i) + j] = 1 -            if i != H - 1 and S[i][j] == "." and S[i + 1][j] == ".": -                dp[(W * i) + j][(W * (i + 1)) + j] = 1 -                dp[(W * (i + 1)) + j][(W * i) + j] = 1 -            dp[(W * i) + j][(W * i) + j] = 0 -    N = H * W -    for k in range(N): -        for i in range(N): -            for j in range(N): -                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]) -    ans = 0 -    for i in range(N): -        for j in range(N): -            if dp[i][j] != INF: -                ans = max(ans, dp[i][j]) -    print(ans) - - -if __name__ == "__main__": -    main() +H, W = list(map(int, input().split())) +S = [eval(input()) for _ in range(H)] +ans = 0 +dyx = [(1, 0), (0, 1), (-1, 0), (0, -1)] +for i in range(H): +    for j in range(W): +        if S[i][j] == "#": +            continue +        dist = [[0 for _ in range(W)] for _ in range(H)] +        visited = [[False for _ in range(W)] for _ in range(H)] +        visited[i][j] = True +        q = deque() +        q.append((i, j)) +        while q: +            y, x = q.popleft() +            for dy, dx in dyx: +                ny, nx = y + dy, x + dx +                if ( +                    not 0 <= ny <= H - 1 +                    or not 0 <= nx <= W - 1 +                    or visited[ny][nx] == True +                    or S[ny][nx] == "#" +                ): +                    continue +                q.append((ny, nx)) +                dist[ny][nx] = dist[y][x] + 1 +                visited[ny][nx] = True +        ans = max(ans, max(max(row) for row in dist)) +print(ans)