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

field=[]

field.append([True for i in range(w+2)])

start=[]

for i  in range(h):

    s=eval(input())

    sub=[True]

    for j in range(w):

        if s[j]=="#":

            sub.append(True)

        else:

            sub.append(False)

            start.append((i+1,j+1))

    

    sub.append(True)

    field.append(sub)



            

        

    

field.append([True for i in range(w+2)])



from collections import deque

import copy

dis=[]

for i in range(len(start)):



        fields=copy.deepcopy(field)

        d=deque()

        e=deque()

        distance=0

        fields[start[i][0]][start[i][1]]=True



        d.append((start[i][0],start[i][1]))

        while d:

            for some in d:

                index1,index2=some[0],some[1]

                if fields[index1-1][index2]==False:

                    fields[index1-1][index2]=True

                    e.append((index1-1,index2))

                if fields[index1+1][index2]==False:

                    fields[index1+1][index2]=True

                    e.append((index1+1,index2))

                if fields[index1][index2+1]==False:

                    fields[index1][index2+1]=True

                    e.append((index1,index2+1))

                if  fields[index1][index2-1]==False:

                    fields[index1][index2-1]=True

                    e.append((index1,index2-1))

            distance+=1

            d=e

            e=deque()



        dis.append(distance)

    





print((max(dis)  -1))      

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

data=[]

data.append(list("#"*(w+2)))

for i in range(h):

    s=eval(input())

    s="#"+s+"#"

    lists=list(s)

    data.append(lists)

data.append("#"*(w+2))

s=0

uselist=[]

graph={i:[] for i in range(1,h*w+1)}

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

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

        if data[i][j]==".":

            a=w*(i-1)+j

            uselist.append(a)

            if data[i+1][j]==".":

                b=w*(i)+j

                graph[b].append(a)

                graph[a].append(b)



            if data[i][j+1]==".":

                b=w*(i-1)+j+1

                graph[b].append(a)

                graph[a].append(b)



from collections import deque



def how_far_from(s,n):

    d=deque()

#頂点sからどのくらいの距離にあるのかを返す関数

    parent=[0 for i in range(n+1)]

    visited=[False for i in range(n+1)]

    visited[s]=True

    d.append((s,0))



    how_far={i:[] for i in range(n+1)}

    while d:

        node=d.popleft()

        for point in graph[node[0]]:

            if visited[point]==False:

      

                visited[point]=True



                d.append((point,node[1]+1))

                how_far[node[1]+1].append(point)



    return how_far

maxi=0

for s in uselist:

    Q=how_far_from(s,h*w)



    for i in range(h*w,-1,-1):

        if Q[i]:

            maxi=max(maxi,i)

            break

print(maxi)   
h, w = list(map(int, input().split()))
field = []
field.append([True for i in range(w + 2)])
start = []
for i in range(h):
    s = eval(input())
    sub = [True]
    for j in range(w):
        if s[j] == "#":
            sub.append(True)
        else:
            sub.append(False)
            start.append((i + 1, j + 1))
    sub.append(True)
    field.append(sub)
field.append([True for i in range(w + 2)])
from collections import deque
import copy

dis = []
for i in range(len(start)):
    fields = copy.deepcopy(field)
    d = deque()
    e = deque()
    distance = 0
    fields[start[i][0]][start[i][1]] = True
    d.append((start[i][0], start[i][1]))
    while d:
        for some in d:
            index1, index2 = some[0], some[1]
            if fields[index1 - 1][index2] == False:
                fields[index1 - 1][index2] = True
                e.append((index1 - 1, index2))
            if fields[index1 + 1][index2] == False:
                fields[index1 + 1][index2] = True
                e.append((index1 + 1, index2))
            if fields[index1][index2 + 1] == False:
                fields[index1][index2 + 1] = True
                e.append((index1, index2 + 1))
            if fields[index1][index2 - 1] == False:
                fields[index1][index2 - 1] = True
                e.append((index1, index2 - 1))
        distance += 1
        d = e
        e = deque()
    dis.append(distance)
print((max(dis) - 1))

h, w = list(map(int, input().split()))
data = []
data.append(list("#" * (w + 2)))
for i in range(h):
    s = eval(input())
    s = "#" + s + "#"
    lists = list(s)
    data.append(lists)
data.append("#" * (w + 2))
s = 0
uselist = []
graph = {i: [] for i in range(1, h * w + 1)}
for i in range(1, h + 1):
    for j in range(1, w + 1):
        if data[i][j] == ".":
            a = w * (i - 1) + j
            uselist.append(a)
            if data[i + 1][j] == ".":
                b = w * (i) + j
                graph[b].append(a)
                graph[a].append(b)
            if data[i][j + 1] == ".":
                b = w * (i - 1) + j + 1
                graph[b].append(a)
                graph[a].append(b)
from collections import deque


def how_far_from(s, n):
    d = deque()
    # 頂点sからどのくらいの距離にあるのかを返す関数
    parent = [0 for i in range(n + 1)]
    visited = [False for i in range(n + 1)]
    visited[s] = True
    d.append((s, 0))
    how_far = {i: [] for i in range(n + 1)}
    while d:
        node = d.popleft()
        for point in graph[node[0]]:
            if visited[point] == False:
                visited[point] = True
                d.append((point, node[1] + 1))
                how_far[node[1] + 1].append(point)
    return how_far


maxi = 0
for s in uselist:
    Q = how_far_from(s, h * w)
    for i in range(h * w, -1, -1):
        if Q[i]:
            maxi = max(maxi, i)
            break
print(maxi)

-field = [] -field.append([True for i in range(w + 2)]) -start = [] +data = [] +data.append(list("#" * (w + 2))) -    sub = [True] -    for j in range(w): -        if s[j] == "#": -            sub.append(True) -        else: -            sub.append(False) -            start.append((i + 1, j + 1)) -    sub.append(True) -    field.append(sub) -field.append([True for i in range(w + 2)]) +    s = "#" + s + "#" +    lists = list(s) +    data.append(lists) +data.append("#" * (w + 2)) +s = 0 +uselist = [] +graph = {i: [] for i in range(1, h * w + 1)} +for i in range(1, h + 1): +    for j in range(1, w + 1): +        if data[i][j] == ".": +            a = w * (i - 1) + j +            uselist.append(a) +            if data[i + 1][j] == ".": +                b = w * (i) + j +                graph[b].append(a) +                graph[a].append(b) +            if data[i][j + 1] == ".": +                b = w * (i - 1) + j + 1 +                graph[b].append(a) +                graph[a].append(b) -import copy -dis = [] -for i in range(len(start)): -    fields = copy.deepcopy(field) + +def how_far_from(s, n): -    e = deque() -    distance = 0 -    fields[start[i][0]][start[i][1]] = True -    d.append((start[i][0], start[i][1])) +    # 頂点sからどのくらいの距離にあるのかを返す関数 +    parent = [0 for i in range(n + 1)] +    visited = [False for i in range(n + 1)] +    visited[s] = True +    d.append((s, 0)) +    how_far = {i: [] for i in range(n + 1)} -        for some in d: -            index1, index2 = some[0], some[1] -            if fields[index1 - 1][index2] == False: -                fields[index1 - 1][index2] = True -                e.append((index1 - 1, index2)) -            if fields[index1 + 1][index2] == False: -                fields[index1 + 1][index2] = True -                e.append((index1 + 1, index2)) -            if fields[index1][index2 + 1] == False: -                fields[index1][index2 + 1] = True -                e.append((index1, index2 + 1)) -            if fields[index1][index2 - 1] == False: -                fields[index1][index2 - 1] = True -                e.append((index1, index2 - 1)) -        distance += 1 -        d = e -        e = deque() -    dis.append(distance) -print((max(dis) - 1)) +        node = d.popleft() +        for point in graph[node[0]]: +            if visited[point] == False: +                visited[point] = True +                d.append((point, node[1] + 1)) +                how_far[node[1] + 1].append(point) +    return how_far + + +maxi = 0 +for s in uselist: +    Q = how_far_from(s, h * w) +    for i in range(h * w, -1, -1): +        if Q[i]: +            maxi = max(maxi, i) +            break +print(maxi)