def get_neighbors(pos):
    i, j = pos
    nbrs = []
    for ii in [i - 1, i + 1]:
        if (ii in path_dic) and (j in path_dic[ii]):
            nbrs.append((ii, j))
    for jj in [j - 1, j + 1]:
        if (i in path_dic) and (jj in path_dic[i]):
            nbrs.append((i, jj))
    return nbrs

def get_furthest_poss(pos):
    i, j = pos
    decided = set([(i, j)])
    furthest = set([(i, j)])
    dist = 0
    for d in range(n * m):
        next_furthest = set()
        for pos in furthest:
            for nbr in get_neighbors(pos):
                if nbr not in decided:
                    decided.add(nbr)
                    next_furthest.add(nbr)
        if len(next_furthest) > 0:
            dist = d + 1
            furthest = next_furthest
        else:
            break
    return dist, furthest

def get_longest_dist():
    for i, js in path_dic.items():
        if len(js) > 0:
            init_pos = (i, js[0])
            break
    d1, poss1 = get_furthest_poss(init_pos)
    d2, poss2 = get_furthest_poss(poss1.pop())
    dd = d2 - d1
    while dd > 0:
        d1, poss1 = (d2, poss2)
        d2, poss2 = get_furthest_poss(poss1.pop())
        dd = d2 - d1
    return d2

n, m = list(map(int, input().split()))
path_dic = {i: [j for j, c in enumerate(input()) if c == '.'] for i in range(n)}
print(get_longest_dist())
