'''input

3 3

.#.

#..

.#.

'''

# A coding delight

from sys import stdin, stdout

import gc

gc.disable()

input = stdin.readline

from collections import deque





def mp(arr):

	arr = list(map(str, arr))

	return ' '.join(arr)





def bfs(source):

	myq = deque()

	myq.append(source)

	visited = dict()

	visited[mp(source)] = True

	dist = -1

	while len(myq) > 0:

		temp = deque()

		dist += 1

		while len(myq) > 0:

			x, y  = myq.popleft()

			if x - 1 >= 0:

				if maze[x - 1][y] != '#' and mp([x - 1, y]) not in visited:

					visited[mp([x -1, y])] = True

					temp.append([x - 1, y])

			if x + 1 < n:

				if maze[x + 1][y] != '#' and mp([x + 1, y]) not in visited:

					visited[mp([x + 1, y])] = True

					temp.append([x + 1, y])

			if y - 1 >= 0:

				if maze[x][y - 1] != '#' and mp([x, y - 1]) not in visited:

					visited[mp([x, y - 1])] = True

					temp.append([x, y - 1])

			if y + 1 < m:

				if maze[x][y + 1] != '#' and mp([x, y + 1]) not in visited:

					visited[mp([x, y + 1])] = True

					temp.append([x, y + 1])

		myq = temp

	return dist		





# main starts

n, m = list(map(int, input().split()))

maze = []

for _ in range(n):

	state = list(input().strip())

	maze.append(state)



# from random import randint

# for _ in range(1000):

# maze = []

# n = randint(1, 20)

# m = randint(1, 20)

# for i in range(n):

# 	temp = []

# 	for j in range(m):

# 		k = randint(1, 2)

# 		if k == 1:

# 			temp.append('.')

# 		else:

# 			temp.append('#')

# 	maze.append(temp)



ans = 0

for i in range(n):

	for j in range(m):

		if maze[i][j] != '#':

			first = [i, j]

			ans = max(ans, bfs(first))

print(ans)
'''input

3 3

.#.

#..

.#.

'''

# A coding delight

from sys import stdin, stdout

import gc

gc.disable()

input = stdin.readline

from collections import deque





def mp(arr):

	arr = list(map(str, arr))

	return ' '.join(arr)





def bfs(source):

	myq = deque()

	myq.append(source)

	visited = dict()

	visited[mp(source)] = True

	dist = -1

	while len(myq) > 0:

		temp = deque()

		dist += 1

		while len(myq) > 0:

			x, y  = myq.popleft()

			if x - 1 >= 0 and maze[x - 1][y] != '#' and mp([x - 1, y]) not in visited:

					visited[mp([x -1, y])] = True

					temp.append([x - 1, y])

			if x + 1 < n and maze[x + 1][y] != '#' and mp([x + 1, y]) not in visited:

					visited[mp([x + 1, y])] = True

					temp.append([x + 1, y])

			if y - 1 >= 0 and maze[x][y - 1] != '#' and mp([x, y - 1]) not in visited:

					visited[mp([x, y - 1])] = True

					temp.append([x, y - 1])

			if y + 1 < m and maze[x][y + 1] != '#' and mp([x, y + 1]) not in visited:

					visited[mp([x, y + 1])] = True

					temp.append([x, y + 1])

		myq = temp

	return dist		





# main starts

n, m = list(map(int, input().split()))

maze = []

for _ in range(n):

	state = list(input().strip())

	maze.append(state)



# from random import randint

# for _ in range(1000):

# maze = []

# n = randint(1, 20)

# m = randint(1, 20)

# for i in range(n):

# 	temp = []

# 	for j in range(m):

# 		k = randint(1, 2)

# 		if k == 1:

# 			temp.append('.')

# 		else:

# 			temp.append('#')

# 	maze.append(temp)



ans = 0

for i in range(n):

	for j in range(m):

		if maze[i][j] != '#':

			first = [i, j]

			ans = max(ans, bfs(first))

print(ans)
"""input
3 3
.#.
#..
.#.
"""
# A coding delight
from sys import stdin, stdout
import gc

gc.disable()
input = stdin.readline
from collections import deque


def mp(arr):
    arr = list(map(str, arr))
    return " ".join(arr)


def bfs(source):
    myq = deque()
    myq.append(source)
    visited = dict()
    visited[mp(source)] = True
    dist = -1
    while len(myq) > 0:
        temp = deque()
        dist += 1
        while len(myq) > 0:
            x, y = myq.popleft()
            if x - 1 >= 0:
                if maze[x - 1][y] != "#" and mp([x - 1, y]) not in visited:
                    visited[mp([x - 1, y])] = True
                    temp.append([x - 1, y])
            if x + 1 < n:
                if maze[x + 1][y] != "#" and mp([x + 1, y]) not in visited:
                    visited[mp([x + 1, y])] = True
                    temp.append([x + 1, y])
            if y - 1 >= 0:
                if maze[x][y - 1] != "#" and mp([x, y - 1]) not in visited:
                    visited[mp([x, y - 1])] = True
                    temp.append([x, y - 1])
            if y + 1 < m:
                if maze[x][y + 1] != "#" and mp([x, y + 1]) not in visited:
                    visited[mp([x, y + 1])] = True
                    temp.append([x, y + 1])
        myq = temp
    return dist


# main starts
n, m = list(map(int, input().split()))
maze = []
for _ in range(n):
    state = list(input().strip())
    maze.append(state)
# from random import randint
# for _ in range(1000):
# maze = []
# n = randint(1, 20)
# m = randint(1, 20)
# for i in range(n):
# 	temp = []
# 	for j in range(m):
# 		k = randint(1, 2)
# 		if k == 1:
# 			temp.append('.')
# 		else:
# 			temp.append('#')
# 	maze.append(temp)
ans = 0
for i in range(n):
    for j in range(m):
        if maze[i][j] != "#":
            first = [i, j]
            ans = max(ans, bfs(first))
print(ans)

"""input
3 3
.#.
#..
.#.
"""
# A coding delight
from sys import stdin, stdout
import gc

gc.disable()
input = stdin.readline
from collections import deque


def mp(arr):
    arr = list(map(str, arr))
    return " ".join(arr)


def bfs(source):
    myq = deque()
    myq.append(source)
    visited = dict()
    visited[mp(source)] = True
    dist = -1
    while len(myq) > 0:
        temp = deque()
        dist += 1
        while len(myq) > 0:
            x, y = myq.popleft()
            if x - 1 >= 0 and maze[x - 1][y] != "#" and mp([x - 1, y]) not in visited:
                visited[mp([x - 1, y])] = True
                temp.append([x - 1, y])
            if x + 1 < n and maze[x + 1][y] != "#" and mp([x + 1, y]) not in visited:
                visited[mp([x + 1, y])] = True
                temp.append([x + 1, y])
            if y - 1 >= 0 and maze[x][y - 1] != "#" and mp([x, y - 1]) not in visited:
                visited[mp([x, y - 1])] = True
                temp.append([x, y - 1])
            if y + 1 < m and maze[x][y + 1] != "#" and mp([x, y + 1]) not in visited:
                visited[mp([x, y + 1])] = True
                temp.append([x, y + 1])
        myq = temp
    return dist


# main starts
n, m = list(map(int, input().split()))
maze = []
for _ in range(n):
    state = list(input().strip())
    maze.append(state)
# from random import randint
# for _ in range(1000):
# maze = []
# n = randint(1, 20)
# m = randint(1, 20)
# for i in range(n):
# 	temp = []
# 	for j in range(m):
# 		k = randint(1, 2)
# 		if k == 1:
# 			temp.append('.')
# 		else:
# 			temp.append('#')
# 	maze.append(temp)
ans = 0
for i in range(n):
    for j in range(m):
        if maze[i][j] != "#":
            first = [i, j]
            ans = max(ans, bfs(first))
print(ans)

-            if x - 1 >= 0: -                if maze[x - 1][y] != "#" and mp([x - 1, y]) not in visited: -                    visited[mp([x - 1, y])] = True -                    temp.append([x - 1, y]) -            if x + 1 < n: -                if maze[x + 1][y] != "#" and mp([x + 1, y]) not in visited: -                    visited[mp([x + 1, y])] = True -                    temp.append([x + 1, y]) -            if y - 1 >= 0: -                if maze[x][y - 1] != "#" and mp([x, y - 1]) not in visited: -                    visited[mp([x, y - 1])] = True -                    temp.append([x, y - 1]) -            if y + 1 < m: -                if maze[x][y + 1] != "#" and mp([x, y + 1]) not in visited: -                    visited[mp([x, y + 1])] = True -                    temp.append([x, y + 1]) +            if x - 1 >= 0 and maze[x - 1][y] != "#" and mp([x - 1, y]) not in visited: +                visited[mp([x - 1, y])] = True +                temp.append([x - 1, y]) +            if x + 1 < n and maze[x + 1][y] != "#" and mp([x + 1, y]) not in visited: +                visited[mp([x + 1, y])] = True +                temp.append([x + 1, y]) +            if y - 1 >= 0 and maze[x][y - 1] != "#" and mp([x, y - 1]) not in visited: +                visited[mp([x, y - 1])] = True +                temp.append([x, y - 1]) +            if y + 1 < m and maze[x][y + 1] != "#" and mp([x, y + 1]) not in visited: +                visited[mp([x, y + 1])] = True +                temp.append([x, y + 1])