import copy

from collections import deque





def bfs(H, W, maze, dist, sh, sw):

    queue = deque([[sh, sw]])

    dist[sh][sw] = 0

    while queue:

        h, w = queue.popleft()

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

            next_h, next_w = h + i, w + j

            if not ((0 <= next_h <= H - 1) and (0 <= next_w <= W - 1)):

                continue

            if (maze[next_h][next_w] == ".") and (dist[next_h][next_w] == -1):

                dist[next_h][next_w] = dist[h][w] + 1

                queue.append([next_h, next_w])

    ret = 0

    for i in range(H):

        tmp = max(dist[i])

        if tmp > ret:

            ret = tmp

    return ret





if __name__ == "__main__":

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

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



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

    ans = 0

    for sh in range(H):

        for sw in range(W):

            if S[sh][sw] == "#":

                continue

            d = copy.deepcopy(dist)

            max_move = bfs(H, W, S, d, sh, sw)

            if max_move > ans:

                ans = max_move

    print(ans)

import sys

from collections import deque



input = sys.stdin.readline





def bfs(S, sh, sw, dist):

    dist[sh][sw] = 0

    queue = deque([(sh, sw)])

    while queue:

        h, w = queue.popleft()

        for i, j in ((0, 1), (0, -1), (1, 0), (-1, 0)):

            y, x = h + i, w + j

            if S[y][x] == "#":

                continue

            if dist[y][x] == -1:

                dist[y][x] = dist[h][w] + 1

                queue.append((y, x))





def main():

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

    S = [None] * (H + 2)

    S[0] = S[-1] = "#" * (W + 2)

    for i in range(1, H + 1):

        S[i] = "".join(["#", input().rstrip(), "#"])



    ans = 0

    for sh in range(1, H + 1):

        for sw in range(1, W + 1):

            if S[sh][sw] == "#":

                continue

            dist = [[-1] * (W + 2) for _ in range(H + 2)]

            bfs(S, sh, sw, dist)

            max_dist = max(list(map(max, dist)))

            ans = max(ans, max_dist)



    print(ans)





if __name__ == "__main__":

    main()

import copy
from collections import deque


def bfs(H, W, maze, dist, sh, sw):
    queue = deque([[sh, sw]])
    dist[sh][sw] = 0
    while queue:
        h, w = queue.popleft()
        for i, j in [(1, 0), (-1, 0), (0, -1), (0, 1)]:
            next_h, next_w = h + i, w + j
            if not ((0 <= next_h <= H - 1) and (0 <= next_w <= W - 1)):
                continue
            if (maze[next_h][next_w] == ".") and (dist[next_h][next_w] == -1):
                dist[next_h][next_w] = dist[h][w] + 1
                queue.append([next_h, next_w])
    ret = 0
    for i in range(H):
        tmp = max(dist[i])
        if tmp > ret:
            ret = tmp
    return ret


if __name__ == "__main__":
    H, W = list(map(int, input().split()))
    S = [eval(input()) for _ in range(H)]
    dist = [[-1 for _ in range(W)] for _ in range(H)]
    ans = 0
    for sh in range(H):
        for sw in range(W):
            if S[sh][sw] == "#":
                continue
            d = copy.deepcopy(dist)
            max_move = bfs(H, W, S, d, sh, sw)
            if max_move > ans:
                ans = max_move
    print(ans)

import sys
from collections import deque

input = sys.stdin.readline


def bfs(S, sh, sw, dist):
    dist[sh][sw] = 0
    queue = deque([(sh, sw)])
    while queue:
        h, w = queue.popleft()
        for i, j in ((0, 1), (0, -1), (1, 0), (-1, 0)):
            y, x = h + i, w + j
            if S[y][x] == "#":
                continue
            if dist[y][x] == -1:
                dist[y][x] = dist[h][w] + 1
                queue.append((y, x))


def main():
    H, W = list(map(int, input().split()))
    S = [None] * (H + 2)
    S[0] = S[-1] = "#" * (W + 2)
    for i in range(1, H + 1):
        S[i] = "".join(["#", input().rstrip(), "#"])
    ans = 0
    for sh in range(1, H + 1):
        for sw in range(1, W + 1):
            if S[sh][sw] == "#":
                continue
            dist = [[-1] * (W + 2) for _ in range(H + 2)]
            bfs(S, sh, sw, dist)
            max_dist = max(list(map(max, dist)))
            ans = max(ans, max_dist)
    print(ans)


if __name__ == "__main__":
    main()

-import copy +import sys +input = sys.stdin.readline -def bfs(H, W, maze, dist, sh, sw): -    queue = deque([[sh, sw]]) + +def bfs(S, sh, sw, dist): +    queue = deque([(sh, sw)]) -        for i, j in [(1, 0), (-1, 0), (0, -1), (0, 1)]: -            next_h, next_w = h + i, w + j -            if not ((0 <= next_h <= H - 1) and (0 <= next_w <= W - 1)): +        for i, j in ((0, 1), (0, -1), (1, 0), (-1, 0)): +            y, x = h + i, w + j +            if S[y][x] == "#": -            if (maze[next_h][next_w] == ".") and (dist[next_h][next_w] == -1): -                dist[next_h][next_w] = dist[h][w] + 1 -                queue.append([next_h, next_w]) -    ret = 0 -    for i in range(H): -        tmp = max(dist[i]) -        if tmp > ret: -            ret = tmp -    return ret +            if dist[y][x] == -1: +                dist[y][x] = dist[h][w] + 1 +                queue.append((y, x)) + + +def main(): +    H, W = list(map(int, input().split())) +    S = [None] * (H + 2) +    S[0] = S[-1] = "#" * (W + 2) +    for i in range(1, H + 1): +        S[i] = "".join(["#", input().rstrip(), "#"]) +    ans = 0 +    for sh in range(1, H + 1): +        for sw in range(1, W + 1): +            if S[sh][sw] == "#": +                continue +            dist = [[-1] * (W + 2) for _ in range(H + 2)] +            bfs(S, sh, sw, dist) +            max_dist = max(list(map(max, dist))) +            ans = max(ans, max_dist) +    print(ans) -    H, W = list(map(int, input().split())) -    S = [eval(input()) for _ in range(H)] -    dist = [[-1 for _ in range(W)] for _ in range(H)] -    ans = 0 -    for sh in range(H): -        for sw in range(W): -            if S[sh][sw] == "#": -                continue -            d = copy.deepcopy(dist) -            max_move = bfs(H, W, S, d, sh, sw) -            if max_move > ans: -                ans = max_move -    print(ans) +    main()