from itertools import count, combinations, product



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



grid = [[False]*(W+2) for _ in range(H+2)]



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

    S = eval(input())

    for j,v in zip(list(range(1,W+1)),S):

        grid[i][j] = v == '.'



visited = [[0 if v else float('inf') for v in row] for row in grid]

cnt = 1

def dist(p1,p2):

    global cnt

    q = [p1]

    visited[p1[0]][p1[1]] = cnt 

    for d in count():

        if not q:

            break

        nq = []

        for x,y in q:

            if (x,y) == p2:

                cnt += 1

                return d

            else:

                for dx,dy in ((1,0),(-1,0),(0,1),(0,-1)):

                    if visited[x+dx][y+dy] < cnt:

                        visited[x+dx][y+dy] = cnt

                        nq.append((x+dx,y+dy))

        q = nq

    cnt += 1

    return float('inf')



emp = [(i,j) for i,j in product(list(range(H+2)),list(range(W+2))) if grid[i][j]]



print((max(dist(*p) for p in combinations(emp,2))))
from itertools import count, combinations, product



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



grid = [[False]*(W+2) for _ in range(H+2)]



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

    S = eval(input())

    for j,v in zip(list(range(1,W+1)),S):

        grid[i][j] = v == '.'



visited = [[0 if v else float('inf') for v in row] for row in grid]

cnt = 1

res = 0

for i,j in product(list(range(H+2)),list(range(W+2))):

    if not grid[i][j]:

        continue

    q = [(i,j)]

    visited[i][j] = cnt 

    for d in count():

        if not q:

            break

        nq = []

        for x,y in q:

            for dx,dy in ((1,0),(-1,0),(0,1),(0,-1)):

                if visited[x+dx][y+dy] < cnt:

                    visited[x+dx][y+dy] = cnt

                    nq.append((x+dx,y+dy))

        q = nq

    cnt += 1

    res = max(d-1, res)



print(res)
from itertools import count, combinations, product

H, W = list(map(int, input().split()))
grid = [[False] * (W + 2) for _ in range(H + 2)]
for i in range(1, H + 1):
    S = eval(input())
    for j, v in zip(list(range(1, W + 1)), S):
        grid[i][j] = v == "."
visited = [[0 if v else float("inf") for v in row] for row in grid]
cnt = 1


def dist(p1, p2):
    global cnt
    q = [p1]
    visited[p1[0]][p1[1]] = cnt
    for d in count():
        if not q:
            break
        nq = []
        for x, y in q:
            if (x, y) == p2:
                cnt += 1
                return d
            else:
                for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):
                    if visited[x + dx][y + dy] < cnt:
                        visited[x + dx][y + dy] = cnt
                        nq.append((x + dx, y + dy))
        q = nq
    cnt += 1
    return float("inf")


emp = [(i, j) for i, j in product(list(range(H + 2)), list(range(W + 2))) if grid[i][j]]
print((max(dist(*p) for p in combinations(emp, 2))))

from itertools import count, combinations, product

H, W = list(map(int, input().split()))
grid = [[False] * (W + 2) for _ in range(H + 2)]
for i in range(1, H + 1):
    S = eval(input())
    for j, v in zip(list(range(1, W + 1)), S):
        grid[i][j] = v == "."
visited = [[0 if v else float("inf") for v in row] for row in grid]
cnt = 1
res = 0
for i, j in product(list(range(H + 2)), list(range(W + 2))):
    if not grid[i][j]:
        continue
    q = [(i, j)]
    visited[i][j] = cnt
    for d in count():
        if not q:
            break
        nq = []
        for x, y in q:
            for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):
                if visited[x + dx][y + dy] < cnt:
                    visited[x + dx][y + dy] = cnt
                    nq.append((x + dx, y + dy))
        q = nq
    cnt += 1
    res = max(d - 1, res)
print(res)

- - -def dist(p1, p2): -    global cnt -    q = [p1] -    visited[p1[0]][p1[1]] = cnt +res = 0 +for i, j in product(list(range(H + 2)), list(range(W + 2))): +    if not grid[i][j]: +        continue +    q = [(i, j)] +    visited[i][j] = cnt -            if (x, y) == p2: -                cnt += 1 -                return d -            else: -                for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)): -                    if visited[x + dx][y + dy] < cnt: -                        visited[x + dx][y + dy] = cnt -                        nq.append((x + dx, y + dy)) +            for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)): +                if visited[x + dx][y + dy] < cnt: +                    visited[x + dx][y + dy] = cnt +                    nq.append((x + dx, y + dy)) -    return float("inf") - - -emp = [(i, j) for i, j in product(list(range(H + 2)), list(range(W + 2))) if grid[i][j]] -print((max(dist(*p) for p in combinations(emp, 2)))) +    res = max(d - 1, res) +print(res)