import heapq





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

meiro = []

for i in range(h):

    line = eval(input())

    meiro.append(line)





def dfs(y, x):

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

    if meiro[y][x] == '#':

        return 0

    dist[y][x] = 0



    pattern = [[-1, 0], [1, 0], [0, -1], [0, 1]]

    todo = []

    for dy, dx in pattern:

        ny, nx = y + dy, x + dx

        if 0 <= ny <= h-1 and 0 <= nx <= w-1:

            if meiro[ny][nx] == '.':

                heapq.heappush(todo, [1, ny, nx])



    while todo:

        d, y, x = heapq.heappop(todo)

        if meiro[y][x] == '#':

            continue

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

                continue



        dist[y][x] = d

        for dy, dx in pattern:

            ny, nx = y + dy, x + dx

            if 0 <= ny <= h - 1 and 0 <= nx <= w - 1:

                if dist[ny][nx] == -1 and meiro[ny][nx] == '.':

                    heapq.heappush(todo, [d+1, ny, nx])



    res = 0

    for line in dist:

        res = max(max(line), res)



    return res





ans = []

for y in range(h):

    for x in range(w):

        ans.append(dfs(y, x))



print((max(ans)))

from collections import deque





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

graph = '#' * (w+2)

for _ in range(h):

    line = '#' + eval(input()) + '#'

    graph = graph + line



graph = graph + '#' * (w+2)





def bfs(x):

    if graph[x] == '#':

        return 0

    seen = [-1] * ((h+2)*(w+2))

    seen[x] = 0

    pattern = [-(w+2), -1, 1, w+2]

    todo = deque([])

    for delta in pattern:

        if graph[x+delta] == '.':

            todo.append([x+delta, 1])



    while todo:

        node, dist = todo.popleft()

        if seen[node] != -1:

            continue

        seen[node] = dist

        for delta in pattern:

            if graph[node+delta] == '.' and seen[node+delta] == -1:

                todo.append([node+delta, dist+1])



    return max(seen)





ans = []

for i in range((h+1)*(w+1)):

    ans.append(bfs(i))



print((max(ans)))
import heapq

h, w = list(map(int, input().split()))
meiro = []
for i in range(h):
    line = eval(input())
    meiro.append(line)


def dfs(y, x):
    dist = [[-1] * w for _ in range(h)]
    if meiro[y][x] == "#":
        return 0
    dist[y][x] = 0
    pattern = [[-1, 0], [1, 0], [0, -1], [0, 1]]
    todo = []
    for dy, dx in pattern:
        ny, nx = y + dy, x + dx
        if 0 <= ny <= h - 1 and 0 <= nx <= w - 1:
            if meiro[ny][nx] == ".":
                heapq.heappush(todo, [1, ny, nx])
    while todo:
        d, y, x = heapq.heappop(todo)
        if meiro[y][x] == "#":
            continue
        if dist[y][x] != -1:
            continue
        dist[y][x] = d
        for dy, dx in pattern:
            ny, nx = y + dy, x + dx
            if 0 <= ny <= h - 1 and 0 <= nx <= w - 1:
                if dist[ny][nx] == -1 and meiro[ny][nx] == ".":
                    heapq.heappush(todo, [d + 1, ny, nx])
    res = 0
    for line in dist:
        res = max(max(line), res)
    return res


ans = []
for y in range(h):
    for x in range(w):
        ans.append(dfs(y, x))
print((max(ans)))

from collections import deque

h, w = list(map(int, input().split()))
graph = "#" * (w + 2)
for _ in range(h):
    line = "#" + eval(input()) + "#"
    graph = graph + line
graph = graph + "#" * (w + 2)


def bfs(x):
    if graph[x] == "#":
        return 0
    seen = [-1] * ((h + 2) * (w + 2))
    seen[x] = 0
    pattern = [-(w + 2), -1, 1, w + 2]
    todo = deque([])
    for delta in pattern:
        if graph[x + delta] == ".":
            todo.append([x + delta, 1])
    while todo:
        node, dist = todo.popleft()
        if seen[node] != -1:
            continue
        seen[node] = dist
        for delta in pattern:
            if graph[node + delta] == "." and seen[node + delta] == -1:
                todo.append([node + delta, dist + 1])
    return max(seen)


ans = []
for i in range((h + 1) * (w + 1)):
    ans.append(bfs(i))
print((max(ans)))

-import heapq +from collections import deque -meiro = [] -for i in range(h): -    line = eval(input()) -    meiro.append(line) +graph = "#" * (w + 2) +for _ in range(h): +    line = "#" + eval(input()) + "#" +    graph = graph + line +graph = graph + "#" * (w + 2) -def dfs(y, x): -    dist = [[-1] * w for _ in range(h)] -    if meiro[y][x] == "#": +def bfs(x): +    if graph[x] == "#": -    dist[y][x] = 0 -    pattern = [[-1, 0], [1, 0], [0, -1], [0, 1]] -    todo = [] -    for dy, dx in pattern: -        ny, nx = y + dy, x + dx -        if 0 <= ny <= h - 1 and 0 <= nx <= w - 1: -            if meiro[ny][nx] == ".": -                heapq.heappush(todo, [1, ny, nx]) +    seen = [-1] * ((h + 2) * (w + 2)) +    seen[x] = 0 +    pattern = [-(w + 2), -1, 1, w + 2] +    todo = deque([]) +    for delta in pattern: +        if graph[x + delta] == ".": +            todo.append([x + delta, 1]) -        d, y, x = heapq.heappop(todo) -        if meiro[y][x] == "#": +        node, dist = todo.popleft() +        if seen[node] != -1: -        if dist[y][x] != -1: -            continue -        dist[y][x] = d -        for dy, dx in pattern: -            ny, nx = y + dy, x + dx -            if 0 <= ny <= h - 1 and 0 <= nx <= w - 1: -                if dist[ny][nx] == -1 and meiro[ny][nx] == ".": -                    heapq.heappush(todo, [d + 1, ny, nx]) -    res = 0 -    for line in dist: -        res = max(max(line), res) -    return res +        seen[node] = dist +        for delta in pattern: +            if graph[node + delta] == "." and seen[node + delta] == -1: +                todo.append([node + delta, dist + 1]) +    return max(seen) -for y in range(h): -    for x in range(w): -        ans.append(dfs(y, x)) +for i in range((h + 1) * (w + 1)): +    ans.append(bfs(i))