import copy

from collections import deque



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

field_s = []



# フィールドを作る

for h in range(H + 2):

    field_s.append(["#"] * (W + 2))

    if 1 <= h <= (H):

        field_s[h][1:-1] = list(map(str, input().rstrip()))



#　動き方のセットを準備

moves = [[1, 0], [-1, 0], [0, 1], [0, -1]]



# スタート座標を取得

start = []

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

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

        if field_s[y][x] == ".":

            start.append([y, x])



# 答え

ans = 0



for s in start:



    # fieldの初期化

    field = copy.deepcopy(field_s)



    # startをキューに追加

    que = deque([s])



    # startの距離は0に

    field[s[0]][s[1]] = 0



    # キューに何かがある限り探索を続ける

    while que:

        c = que.popleft()



        # 今の距離

        dist = field[c[0]][c[1]]



        # 動いた先が「.」なら、距離を記録してキューに追加

        for m in moves:

            my = c[0] + m[0]

            mx = c[1] + m[1]



            if field[my][mx] == ".":

                field[my][mx] = dist + 1

                que.append([my, mx])

            else:

                continue



    # キューを消化したら最大値を取り出す

    field = sum(field, [])

    ans = max(ans, max([x for x in field if type(x) == int]))



print(ans)
import copy

from collections import deque





def bfs(s, f):

    f[s[0]][s[1]] = 0

    moves = [[1, 0], [-1, 0], [0, 1], [0, -1]]



    q = deque([s])

    while q:

        c = q.popleft()

        for m in moves:

            my, mx = c[0] + m[0], c[1] + m[1]



            if f[my][mx] == ".":

                f[my][mx] = f[c[0]][c[1]] + 1

                q.append([my, mx])

            else:

                continue



    f = sum(f, [])

    return max([x for x in f if type(x) == int])





def main():

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

    field_s = []



    for h in range(H + 2):

        field_s.append(["#"] * (W + 2))

        if 1 <= h <= (H):

            field_s[h][1:-1] = list(map(str, input().rstrip()))



    start = []

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

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

            if field_s[y][x] == ".":

                start.append([y, x])



    ans = 0

    for s in start:

        field = copy.deepcopy(field_s)

        ans = max(ans, bfs(s, field))



    print(ans)





if __name__ == '__main__':

    main()
import copy
from collections import deque

H, W = list(map(int, input().split()))
field_s = []
# フィールドを作る
for h in range(H + 2):
    field_s.append(["#"] * (W + 2))
    if 1 <= h <= (H):
        field_s[h][1:-1] = list(map(str, input().rstrip()))
# 　動き方のセットを準備
moves = [[1, 0], [-1, 0], [0, 1], [0, -1]]
# スタート座標を取得
start = []
for y in range(1, H + 1):
    for x in range(1, W + 1):
        if field_s[y][x] == ".":
            start.append([y, x])
# 答え
ans = 0
for s in start:
    # fieldの初期化
    field = copy.deepcopy(field_s)
    # startをキューに追加
    que = deque([s])
    # startの距離は0に
    field[s[0]][s[1]] = 0
    # キューに何かがある限り探索を続ける
    while que:
        c = que.popleft()
        # 今の距離
        dist = field[c[0]][c[1]]
        # 動いた先が「.」なら、距離を記録してキューに追加
        for m in moves:
            my = c[0] + m[0]
            mx = c[1] + m[1]
            if field[my][mx] == ".":
                field[my][mx] = dist + 1
                que.append([my, mx])
            else:
                continue
    # キューを消化したら最大値を取り出す
    field = sum(field, [])
    ans = max(ans, max([x for x in field if type(x) == int]))
print(ans)

import copy
from collections import deque


def bfs(s, f):
    f[s[0]][s[1]] = 0
    moves = [[1, 0], [-1, 0], [0, 1], [0, -1]]
    q = deque([s])
    while q:
        c = q.popleft()
        for m in moves:
            my, mx = c[0] + m[0], c[1] + m[1]
            if f[my][mx] == ".":
                f[my][mx] = f[c[0]][c[1]] + 1
                q.append([my, mx])
            else:
                continue
    f = sum(f, [])
    return max([x for x in f if type(x) == int])


def main():
    H, W = list(map(int, input().split()))
    field_s = []
    for h in range(H + 2):
        field_s.append(["#"] * (W + 2))
        if 1 <= h <= (H):
            field_s[h][1:-1] = list(map(str, input().rstrip()))
    start = []
    for y in range(1, H + 1):
        for x in range(1, W + 1):
            if field_s[y][x] == ".":
                start.append([y, x])
    ans = 0
    for s in start:
        field = copy.deepcopy(field_s)
        ans = max(ans, bfs(s, field))
    print(ans)


if __name__ == "__main__":
    main()

-H, W = list(map(int, input().split())) -field_s = [] -# フィールドを作る -for h in range(H + 2): -    field_s.append(["#"] * (W + 2)) -    if 1 <= h <= (H): -        field_s[h][1:-1] = list(map(str, input().rstrip())) -# 　動き方のセットを準備 -moves = [[1, 0], [-1, 0], [0, 1], [0, -1]] -# スタート座標を取得 -start = [] -for y in range(1, H + 1): -    for x in range(1, W + 1): -        if field_s[y][x] == ".": -            start.append([y, x]) -# 答え -ans = 0 -for s in start: -    # fieldの初期化 -    field = copy.deepcopy(field_s) -    # startをキューに追加 -    que = deque([s]) -    # startの距離は0に -    field[s[0]][s[1]] = 0 -    # キューに何かがある限り探索を続ける -    while que: -        c = que.popleft() -        # 今の距離 -        dist = field[c[0]][c[1]] -        # 動いた先が「.」なら、距離を記録してキューに追加 + +def bfs(s, f): +    f[s[0]][s[1]] = 0 +    moves = [[1, 0], [-1, 0], [0, 1], [0, -1]] +    q = deque([s]) +    while q: +        c = q.popleft() -            my = c[0] + m[0] -            mx = c[1] + m[1] -            if field[my][mx] == ".": -                field[my][mx] = dist + 1 -                que.append([my, mx]) +            my, mx = c[0] + m[0], c[1] + m[1] +            if f[my][mx] == ".": +                f[my][mx] = f[c[0]][c[1]] + 1 +                q.append([my, mx]) -    # キューを消化したら最大値を取り出す -    field = sum(field, []) -    ans = max(ans, max([x for x in field if type(x) == int])) -print(ans) +    f = sum(f, []) +    return max([x for x in f if type(x) == int]) + + +def main(): +    H, W = list(map(int, input().split())) +    field_s = [] +    for h in range(H + 2): +        field_s.append(["#"] * (W + 2)) +        if 1 <= h <= (H): +            field_s[h][1:-1] = list(map(str, input().rstrip())) +    start = [] +    for y in range(1, H + 1): +        for x in range(1, W + 1): +            if field_s[y][x] == ".": +                start.append([y, x]) +    ans = 0 +    for s in start: +        field = copy.deepcopy(field_s) +        ans = max(ans, bfs(s, field)) +    print(ans) + + +if __name__ == "__main__": +    main()