from queue import Queue

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

MAZE = ['#'*(w+2)]

for _ in range(h):

    MAZE.append("#"+eval(input())+"#")

else:

    MAZE.append('#'*(w+2))



INF = 10**3

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





def bfs(init_x, init_y):

    dist = [[INF]*(w+2) for _ in range(h+2)]

    q = Queue()

    q.put((init_x, init_y))

    dist[init_x][init_y] = 0

    MAX = 0

    while not q.empty():

        x, y = q.get()

        for i, j in directions:

            if MAZE[x+i][y+j] == '#':

                continue

            if dist[x+i][y+j] <= dist[x][y]+1:

                continue

            dist[x+i][y+j] = dist[x][y]+1

            q.put((x+i, y+j))

        MAX = max(MAX, dist[x][y])

    return MAX





ans = 0

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

    for j in range(1, w+1):

        if MAZE[i][j] == '#':

            continue

        ans = max(ans, bfs(i, j))

print(ans)

from collections import deque

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

MAZE = ['#'*(w+2)]

for _ in range(h):

    MAZE.append("#"+eval(input())+"#")

else:

    MAZE.append('#'*(w+2))



INF = 10**3

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





def bfs(init_x, init_y):

    dist = [[INF]*(w+2) for _ in range(h+2)]

    q = deque([(init_x, init_y)])

    dist[init_x][init_y] = 0

    MAX = 0

    while q:

        x, y = q.popleft()

        for i, j in directions:

            if MAZE[x+i][y+j] == '#':

                continue

            if dist[x+i][y+j] <= dist[x][y]+1:

                continue

            dist[x+i][y+j] = dist[x][y]+1

            q.append((x+i, y+j))



        MAX = max(MAX, dist[x][y])

    return MAX





ans = 0

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

    for j in range(1, w+1):

        if MAZE[i][j] == '#':

            continue

        ans = max(ans, bfs(i, j))

print(ans)

from queue import Queue

h, w = list(map(int, input().split()))
MAZE = ["#" * (w + 2)]
for _ in range(h):
    MAZE.append("#" + eval(input()) + "#")
else:
    MAZE.append("#" * (w + 2))
INF = 10**3
directions = [(-1, 0), (0, 1), (1, 0), (0, -1)]


def bfs(init_x, init_y):
    dist = [[INF] * (w + 2) for _ in range(h + 2)]
    q = Queue()
    q.put((init_x, init_y))
    dist[init_x][init_y] = 0
    MAX = 0
    while not q.empty():
        x, y = q.get()
        for i, j in directions:
            if MAZE[x + i][y + j] == "#":
                continue
            if dist[x + i][y + j] <= dist[x][y] + 1:
                continue
            dist[x + i][y + j] = dist[x][y] + 1
            q.put((x + i, y + j))
        MAX = max(MAX, dist[x][y])
    return MAX


ans = 0
for i in range(1, h + 1):
    for j in range(1, w + 1):
        if MAZE[i][j] == "#":
            continue
        ans = max(ans, bfs(i, j))
print(ans)

from collections import deque

h, w = list(map(int, input().split()))
MAZE = ["#" * (w + 2)]
for _ in range(h):
    MAZE.append("#" + eval(input()) + "#")
else:
    MAZE.append("#" * (w + 2))
INF = 10**3
directions = [(-1, 0), (0, 1), (1, 0), (0, -1)]


def bfs(init_x, init_y):
    dist = [[INF] * (w + 2) for _ in range(h + 2)]
    q = deque([(init_x, init_y)])
    dist[init_x][init_y] = 0
    MAX = 0
    while q:
        x, y = q.popleft()
        for i, j in directions:
            if MAZE[x + i][y + j] == "#":
                continue
            if dist[x + i][y + j] <= dist[x][y] + 1:
                continue
            dist[x + i][y + j] = dist[x][y] + 1
            q.append((x + i, y + j))
        MAX = max(MAX, dist[x][y])
    return MAX


ans = 0
for i in range(1, h + 1):
    for j in range(1, w + 1):
        if MAZE[i][j] == "#":
            continue
        ans = max(ans, bfs(i, j))
print(ans)

-from queue import Queue +from collections import deque -    q = Queue() -    q.put((init_x, init_y)) +    q = deque([(init_x, init_y)]) -    while not q.empty(): -        x, y = q.get() +    while q: +        x, y = q.popleft() -            q.put((x + i, y + j)) +            q.append((x + i, y + j))