module maze_master;

import std.stdio;
import std.algorithm;
import std.container.dlist;
import std.typecons;

alias Vector2 = Tuple!(int, "x", int, "y");

int h, w;
char[20][20] maze;
int[Vector2[2]] moves;
bool[20][20] visited;

void bfs(int x, int y)
{
    auto path = DList!(Vector2)(Vector2(x, y));
    visited = visited.init;
    visited[y][x] = true;
    auto move = 0;
    auto from = Vector2(x, y);

    while (!path.empty)
    {
        ++move;
        immutable first = path.front;
        path.removeFront;
        foreach (d; [[0, -1], [1, 0], [0, 1], [-1, 0]])
        {
            auto dx = d[0], dy = d[1];
            auto cx = first.x + dx, cy = first.y + dy;
            if (cx < 0 || cx >= w || cy < 0 || cy >= h || maze[cy][cx] == '#' || visited[cy][cx])
                continue;
            visited[cy][cx] = true;
            auto to = Vector2(cx, cy);
            Vector2[2] key = [from, to];
            moves[key] = min(move, moves.get(key, move));
            path.insertBack(to);
        }
    }
}

void main(string[] args)
{
    readf("%d %d\n", &h, &w);
    foreach (y; 0 .. h)
    {
        foreach (x; 0 .. w)
        {
            readf("%c", &maze[y][x]);
        }
        readln();
    }

    foreach (y; 0 .. h)
    {
        foreach (x; 0 .. w)
        {
            bfs(x, y);
        }
    }

    debug
    {
        writeln(moves);
    }

    writefln("%d", moves.byValue.maxElement);
}
