# BFS queue

import queue

import copy

import time

sss = time.time()

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

b = [list(eval(input())) for _ in range(H)]

dist = [[10**2 for _ in range(W)] for _ in range(H)]

start = (-1,-1)

qq = queue.Queue()

# start把握

for i in range(H):

    for j in range(W):

        if b[i][j] == '.':

            qq.put((i,j))

far = 0

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

def BFS(start, bb):

    dist = [[10**2 for _ in range(W)] for _ in range(H)]

    far = 0

    q = queue.Queue()

    q.put(start)

    dist[start[0]][start[1]] = 0

    # BFS

    while 1:

        now = q.get()

        x = now[0]

        y = now[1]

        olddist = dist[x][y]

        bb[x][y] = '#'

        for elem in move:

            dx = elem[0]

            dy = elem[1]

            xx = x+dx

            yy = y+dy

            if xx>=0 and xx<= H-1 and yy>=0 and yy<=W-1:

                if bb[xx][yy] != '#':

                    if dist[xx][yy] == 10**2:

                        dist[xx][yy] = olddist + 1

                        far = max([far,olddist+1])

                        q.put((xx,yy))

        if q.empty():

            break

    return far

res = 0

while 1:

    ttt = time.time()

    if sss-ttt >= 1.8:

        break

    now = qq.get()

    res = max([res, BFS(now, copy.deepcopy(b))])

    if qq.empty():

        break

print(res)

# BFS queue

import queue

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

b = [list(eval(input())) for _ in range(H)]

dist = [[100]*W for _ in range(H)]

start = (-1,-1)

qq = queue.Queue()

# start把握

for i in range(H):

    for j in range(W):

        if b[i][j] == '.':

            qq.put((i,j))

far = 0

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

def BFS(start):

    dist = [[100]*W for _ in range(H)]

    far = 0

    q = queue.Queue()

    q.put(start)

    dist[start[0]][start[1]] = 0

    # BFS

    while 1:

        now = q.get()

        x = now[0]

        y = now[1]

        olddist = dist[x][y]

        for elem in move:

            dx = elem[0]

            dy = elem[1]

            xx = x+dx

            yy = y+dy

            if xx>=0 and xx<= H-1 and yy>=0 and yy<=W-1:

                if b[xx][yy] != '#':

                    if dist[xx][yy] == 100:

                        dist[xx][yy] = olddist + 1

                        if far < olddist+1:

                            far = olddist+1

                        q.put((xx,yy))

        if q.empty():

            break

    return far

res = 0

while 1:

    now = qq.get()

    res = max([res, BFS(now)])

    if qq.empty():

        break

print(res)

# BFS queue
import queue
import copy
import time

sss = time.time()
H, W = list(map(int, input().split()))
b = [list(eval(input())) for _ in range(H)]
dist = [[10**2 for _ in range(W)] for _ in range(H)]
start = (-1, -1)
qq = queue.Queue()
# start把握
for i in range(H):
    for j in range(W):
        if b[i][j] == ".":
            qq.put((i, j))
far = 0
move = [(-1, 0), (0, -1), (1, 0), (0, 1)]


def BFS(start, bb):
    dist = [[10**2 for _ in range(W)] for _ in range(H)]
    far = 0
    q = queue.Queue()
    q.put(start)
    dist[start[0]][start[1]] = 0
    # BFS
    while 1:
        now = q.get()
        x = now[0]
        y = now[1]
        olddist = dist[x][y]
        bb[x][y] = "#"
        for elem in move:
            dx = elem[0]
            dy = elem[1]
            xx = x + dx
            yy = y + dy
            if xx >= 0 and xx <= H - 1 and yy >= 0 and yy <= W - 1:
                if bb[xx][yy] != "#":
                    if dist[xx][yy] == 10**2:
                        dist[xx][yy] = olddist + 1
                        far = max([far, olddist + 1])
                        q.put((xx, yy))
        if q.empty():
            break
    return far


res = 0
while 1:
    ttt = time.time()
    if sss - ttt >= 1.8:
        break
    now = qq.get()
    res = max([res, BFS(now, copy.deepcopy(b))])
    if qq.empty():
        break
print(res)

# BFS queue
import queue

H, W = list(map(int, input().split()))
b = [list(eval(input())) for _ in range(H)]
dist = [[100] * W for _ in range(H)]
start = (-1, -1)
qq = queue.Queue()
# start把握
for i in range(H):
    for j in range(W):
        if b[i][j] == ".":
            qq.put((i, j))
far = 0
move = [(-1, 0), (0, -1), (1, 0), (0, 1)]


def BFS(start):
    dist = [[100] * W for _ in range(H)]
    far = 0
    q = queue.Queue()
    q.put(start)
    dist[start[0]][start[1]] = 0
    # BFS
    while 1:
        now = q.get()
        x = now[0]
        y = now[1]
        olddist = dist[x][y]
        for elem in move:
            dx = elem[0]
            dy = elem[1]
            xx = x + dx
            yy = y + dy
            if xx >= 0 and xx <= H - 1 and yy >= 0 and yy <= W - 1:
                if b[xx][yy] != "#":
                    if dist[xx][yy] == 100:
                        dist[xx][yy] = olddist + 1
                        if far < olddist + 1:
                            far = olddist + 1
                        q.put((xx, yy))
        if q.empty():
            break
    return far


res = 0
while 1:
    now = qq.get()
    res = max([res, BFS(now)])
    if qq.empty():
        break
print(res)

-import copy -import time -sss = time.time() -dist = [[10**2 for _ in range(W)] for _ in range(H)] +dist = [[100] * W for _ in range(H)] -def BFS(start, bb): -    dist = [[10**2 for _ in range(W)] for _ in range(H)] +def BFS(start): +    dist = [[100] * W for _ in range(H)] -        bb[x][y] = "#" -                if bb[xx][yy] != "#": -                    if dist[xx][yy] == 10**2: +                if b[xx][yy] != "#": +                    if dist[xx][yy] == 100: -                        far = max([far, olddist + 1]) +                        if far < olddist + 1: +                            far = olddist + 1 -    ttt = time.time() -    if sss - ttt >= 1.8: -        break -    res = max([res, BFS(now, copy.deepcopy(b))]) +    res = max([res, BFS(now)])