# Author: cr4zjh0bp

# Created: Tue Mar 17 19:50:06 UTC 2020

import sys

 

stdin = sys.stdin

inf = 1 << 60

mod = 1000000007

 

ni      = lambda: int(ns())

nin     = lambda y: [ni() for _ in range(y)]

na      = lambda: list(map(int, stdin.readline().split()))

nan     = lambda y: [na() for _ in range(y)]

nf      = lambda: float(ns())

nfn     = lambda y: [nf() for _ in range(y)]

nfa     = lambda: list(map(float, stdin.readline().split()))

nfan    = lambda y: [nfa() for _ in range(y)]

ns      = lambda: stdin.readline().rstrip()

nsn     = lambda y: [ns() for _ in range(y)]

ncl     = lambda y: [list(ns()) for _ in range(y)]

nas     = lambda: stdin.readline().split()



h, w = na()

m = nsn(h)



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

dx, dy = [0, 1, -1, 0], [1, 0, 0, -1]

for i in range(h):

    for j in range(w):

        for k in range(4):

            ni, nj = i + dy[k], j + dx[k]

            if ni >= 0 and ni < h and nj >= 0 and nj < w and m[ni][nj] != '#' and m[i][j] != '#':

                dist[i * w + j][ni * w + nj] = 1

        dist[i * w + j][i * w + j] = 0



def floyd_warshall(n, dist):

    for i in range(n):

        for j in range(n):

            for k in range(n):

                dist[j][k] = min(dist[j][k], dist[j][i] + dist[i][k])



floyd_warshall(h * w, dist)



ans = 0

for i in range(h * w):

    for j in range(h * w):

        if dist[i][j] != inf:

            ans = max(ans, dist[i][j])



print(ans)
import sys



stdin = sys.stdin

inf = 1 << 60

mod = 1000000007



ni      = lambda: int(ns())

nin     = lambda y: [ni() for _ in range(y)]

na      = lambda: list(map(int, stdin.readline().split()))

nan     = lambda y: [na() for _ in range(y)]

nf      = lambda: float(ns())

nfn     = lambda y: [nf() for _ in range(y)]

nfa     = lambda: list(map(float, stdin.readline().split()))

nfan    = lambda y: [nfa() for _ in range(y)]

ns      = lambda: stdin.readline().rstrip()

nsn     = lambda y: [ns() for _ in range(y)]

ncl     = lambda y: [list(ns()) for _ in range(y)]

nas     = lambda: stdin.readline().split()



from collections import deque



h, w = na()

maze = nsn(h)



def bfs(sx, sy):

    q = deque()

    q.append((sx, sy))

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

    dist[sy][sx] = 0

    dx, dy = [1, 0, 0, -1], [0, 1, -1, 0]

    res = 0

    while len(q):

        p = q.popleft()

        cx, cy = p

        for i in range(4):

            nx, ny = cx + dx[i], cy + dy[i]

            if nx < 0 or nx >= w:

                continue

            if ny < 0 or ny >= h:

                continue

            if dist[ny][nx] != inf:

                continue

            if maze[ny][nx] == '#':

                continue

            update = dist[cy][cx] + 1

            dist[ny][nx] = update

            res = max(res, update)

            q.append((nx, ny))

    

    return res



ans = 0



for y in range(h):

    for x in range(w):

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

            continue

        ans = max(ans, bfs(x, y))



print(ans)
# Author: cr4zjh0bp
# Created: Tue Mar 17 19:50:06 UTC 2020
import sys

stdin = sys.stdin
inf = 1 << 60
mod = 1000000007
ni = lambda: int(ns())
nin = lambda y: [ni() for _ in range(y)]
na = lambda: list(map(int, stdin.readline().split()))
nan = lambda y: [na() for _ in range(y)]
nf = lambda: float(ns())
nfn = lambda y: [nf() for _ in range(y)]
nfa = lambda: list(map(float, stdin.readline().split()))
nfan = lambda y: [nfa() for _ in range(y)]
ns = lambda: stdin.readline().rstrip()
nsn = lambda y: [ns() for _ in range(y)]
ncl = lambda y: [list(ns()) for _ in range(y)]
nas = lambda: stdin.readline().split()
h, w = na()
m = nsn(h)
dist = [[inf] * (h * w) for _ in range(h * w)]
dx, dy = [0, 1, -1, 0], [1, 0, 0, -1]
for i in range(h):
    for j in range(w):
        for k in range(4):
            ni, nj = i + dy[k], j + dx[k]
            if (
                ni >= 0
                and ni < h
                and nj >= 0
                and nj < w
                and m[ni][nj] != "#"
                and m[i][j] != "#"
            ):
                dist[i * w + j][ni * w + nj] = 1
        dist[i * w + j][i * w + j] = 0


def floyd_warshall(n, dist):
    for i in range(n):
        for j in range(n):
            for k in range(n):
                dist[j][k] = min(dist[j][k], dist[j][i] + dist[i][k])


floyd_warshall(h * w, dist)
ans = 0
for i in range(h * w):
    for j in range(h * w):
        if dist[i][j] != inf:
            ans = max(ans, dist[i][j])
print(ans)

import sys

stdin = sys.stdin
inf = 1 << 60
mod = 1000000007
ni = lambda: int(ns())
nin = lambda y: [ni() for _ in range(y)]
na = lambda: list(map(int, stdin.readline().split()))
nan = lambda y: [na() for _ in range(y)]
nf = lambda: float(ns())
nfn = lambda y: [nf() for _ in range(y)]
nfa = lambda: list(map(float, stdin.readline().split()))
nfan = lambda y: [nfa() for _ in range(y)]
ns = lambda: stdin.readline().rstrip()
nsn = lambda y: [ns() for _ in range(y)]
ncl = lambda y: [list(ns()) for _ in range(y)]
nas = lambda: stdin.readline().split()
from collections import deque

h, w = na()
maze = nsn(h)


def bfs(sx, sy):
    q = deque()
    q.append((sx, sy))
    dist = [[inf] * w for _ in range(h)]
    dist[sy][sx] = 0
    dx, dy = [1, 0, 0, -1], [0, 1, -1, 0]
    res = 0
    while len(q):
        p = q.popleft()
        cx, cy = p
        for i in range(4):
            nx, ny = cx + dx[i], cy + dy[i]
            if nx < 0 or nx >= w:
                continue
            if ny < 0 or ny >= h:
                continue
            if dist[ny][nx] != inf:
                continue
            if maze[ny][nx] == "#":
                continue
            update = dist[cy][cx] + 1
            dist[ny][nx] = update
            res = max(res, update)
            q.append((nx, ny))
    return res


ans = 0
for y in range(h):
    for x in range(w):
        if maze[y][x] == "#":
            continue
        ans = max(ans, bfs(x, y))
print(ans)

-# Author: cr4zjh0bp -# Created: Tue Mar 17 19:50:06 UTC 2020 +from collections import deque + -m = nsn(h) -dist = [[inf] * (h * w) for _ in range(h * w)] -dx, dy = [0, 1, -1, 0], [1, 0, 0, -1] -for i in range(h): -    for j in range(w): -        for k in range(4): -            ni, nj = i + dy[k], j + dx[k] -            if ( -                ni >= 0 -                and ni < h -                and nj >= 0 -                and nj < w -                and m[ni][nj] != "#" -                and m[i][j] != "#" -            ): -                dist[i * w + j][ni * w + nj] = 1 -        dist[i * w + j][i * w + j] = 0 +maze = nsn(h) -def floyd_warshall(n, dist): -    for i in range(n): -        for j in range(n): -            for k in range(n): -                dist[j][k] = min(dist[j][k], dist[j][i] + dist[i][k]) +def bfs(sx, sy): +    q = deque() +    q.append((sx, sy)) +    dist = [[inf] * w for _ in range(h)] +    dist[sy][sx] = 0 +    dx, dy = [1, 0, 0, -1], [0, 1, -1, 0] +    res = 0 +    while len(q): +        p = q.popleft() +        cx, cy = p +        for i in range(4): +            nx, ny = cx + dx[i], cy + dy[i] +            if nx < 0 or nx >= w: +                continue +            if ny < 0 or ny >= h: +                continue +            if dist[ny][nx] != inf: +                continue +            if maze[ny][nx] == "#": +                continue +            update = dist[cy][cx] + 1 +            dist[ny][nx] = update +            res = max(res, update) +            q.append((nx, ny)) +    return res -floyd_warshall(h * w, dist) -for i in range(h * w): -    for j in range(h * w): -        if dist[i][j] != inf: -            ans = max(ans, dist[i][j]) +for y in range(h): +    for x in range(w): +        if maze[y][x] == "#": +            continue +        ans = max(ans, bfs(x, y))