def main():
    H, W = [int(s) for s in input().split()]
    MAP = []
    for h in range(H):
        row = input()
        MAP.append(list(row))

    points = []
    for h in range(H):
        for w in range(W):
            if MAP[h][w] == '.':
                points.append((h, w))

    max_step = 0
    max_way = []
    for start_i in range(len(points) - 1):
        for goal_i in range(start_i + 1, len(points)):
            if points[start_i] in max_way or points[goal_i] in max_way:
                continue
            step, way = count_step(MAP, points[start_i], points[goal_i])
            if step > max_step:
                max_step = step
                max_way = way

    print(max_step)


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


def count_step(MAP, start, goal):
    candidates = [(start, get_distance(start, goal), 0, [start])]

    checked = {}
    while True:
        pos, _, step, way = candidates.pop(0)
        for m in MOVES:
            next_pos = (pos[0] + m[0], pos[1] + m[1])
            if next_pos in checked:
                continue
            if not is_valid(MAP, next_pos):
                continue
            checked[next_pos] = True
            new_way = list(way)
            new_way.append(next_pos)
            distance = get_distance(next_pos, goal)
            if distance == 0:
                return step + 1, new_way
            candidates.append((next_pos, distance, step + 1, new_way))
        candidates.sort(key=lambda x: x[1] + x[2])


def get_distance(p, goal):
    return abs(p[0] - goal[0]) + abs(p[1] - goal[1])


def is_valid(MAP, pos):
    if pos[0] < 0 or pos[1] < 0:
        return False
    if pos[0] >= len(MAP) or pos[1] >= len(MAP[0]):
        return False

    if MAP[pos[0]][pos[1]] == '#':
        return False
    return True


if __name__ == "__main__":
    main()
