import sys

from heapq import heappop, heappush

readline = sys.stdin.readline





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

grid = '#' * (W + 2) + ''.join('#' + readline().strip() +

                               '#' for _ in range(H)) + '#' * (W + 2)

INF = 400





def shortest(grid, start, cost=0):

    dist = [INF] * (H + 2) * (W + 2)

    move = (-1, 1, W + 2, -W - 2)

    st = [start]

    dist[start] = 0

    while(st):

        sx = heappop(st)

        c = dist[sx]

        for a in move:

            x = sx + a

            if grid[x] == '#':

                continue

            dx = dist[sx] + 1

            if dist[x] <= dx:

                continue

            dist[x] = dx

            heappush(st, x)

    return max(x for x in dist if x < INF)





m = 0

for i in range(W + 3, (H + 1) * (W + 2) - 1):

    if grid[i] == '#':

        continue

    tm = shortest(grid, i)

    if m < tm:

        m = tm

print(m)

import sys

from collections import deque

readline = sys.stdin.readline





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

grid = '#' * (W + 2) + ''.join('#' + readline().strip() +

                               '#' for _ in range(H)) + '#' * (W + 2)

INF = 400





def shortest(grid, start, cost=0):

    dist = [INF] * (H + 2) * (W + 2)

    move = (-1, 1, W + 2, -W - 2)

    st = deque([start])

    dist[start] = 0

    while(st):

        sx = st.popleft()

        c = dist[sx]

        for a in move:

            x = sx + a

            if grid[x] == '#':

                continue

            dx = dist[sx] + 1

            if dist[x] <= dx:

                continue

            dist[x] = dx

            st.append(x)

    return max(x for x in dist if x < INF)





m = 0

for i in range(W + 3, (H + 1) * (W + 2) - 1):

    if grid[i] == '#':

        continue

    tm = shortest(grid, i)

    if m < tm:

        m = tm

print(m)

import sys
from heapq import heappop, heappush

readline = sys.stdin.readline
H, W = list(map(int, readline().split()))
grid = (
    "#" * (W + 2)
    + "".join("#" + readline().strip() + "#" for _ in range(H))
    + "#" * (W + 2)
)
INF = 400


def shortest(grid, start, cost=0):
    dist = [INF] * (H + 2) * (W + 2)
    move = (-1, 1, W + 2, -W - 2)
    st = [start]
    dist[start] = 0
    while st:
        sx = heappop(st)
        c = dist[sx]
        for a in move:
            x = sx + a
            if grid[x] == "#":
                continue
            dx = dist[sx] + 1
            if dist[x] <= dx:
                continue
            dist[x] = dx
            heappush(st, x)
    return max(x for x in dist if x < INF)


m = 0
for i in range(W + 3, (H + 1) * (W + 2) - 1):
    if grid[i] == "#":
        continue
    tm = shortest(grid, i)
    if m < tm:
        m = tm
print(m)

import sys
from collections import deque

readline = sys.stdin.readline
H, W = list(map(int, readline().split()))
grid = (
    "#" * (W + 2)
    + "".join("#" + readline().strip() + "#" for _ in range(H))
    + "#" * (W + 2)
)
INF = 400


def shortest(grid, start, cost=0):
    dist = [INF] * (H + 2) * (W + 2)
    move = (-1, 1, W + 2, -W - 2)
    st = deque([start])
    dist[start] = 0
    while st:
        sx = st.popleft()
        c = dist[sx]
        for a in move:
            x = sx + a
            if grid[x] == "#":
                continue
            dx = dist[sx] + 1
            if dist[x] <= dx:
                continue
            dist[x] = dx
            st.append(x)
    return max(x for x in dist if x < INF)


m = 0
for i in range(W + 3, (H + 1) * (W + 2) - 1):
    if grid[i] == "#":
        continue
    tm = shortest(grid, i)
    if m < tm:
        m = tm
print(m)

-from heapq import heappop, heappush +from collections import deque -    st = [start] +    st = deque([start]) -        sx = heappop(st) +        sx = st.popleft() -            heappush(st, x) +            st.append(x)