import std.algorithm, std.array, std.conv, std.range, std.stdio, std.string;
import std.utf;

enum inf = 1 << 24;
void main()
{
    auto buf = readln.chomp.split.to!(int[]);
    immutable height = buf[0], width = buf[1];
    auto map = Map(Grid(buf[0], buf[1]));
    foreach (i; 0..height)
        map.addRow(readln.chomp);
    auto distances = new int[][](map.length, map.length);
    foreach (i, ref row; distances)
        foreach (j, ref elem; row)
            if (i != j) elem = inf;
    foreach (i0; 0..map.height)
        foreach (j0; 0..map.width)
            foreach (d; [[-1, 0], [1, 0], [0, 1], [0, -1]])
            {
                immutable
                        i1 = i0 + d[0],
                        j1 = j0 + d[1];
                debug stderr.writefln("%d, %d - %d, %d", i0, j0, i1, j1);
                if (i1 < 0 || map.height <= i1) continue;
                if (j1 < 0 || map.width <= j1) continue;
                if (map.map[i0][j0] || map.map[i1][j1]) continue;
                debug stderr.writefln("connected");
                distances[map.coordinateToIndex(i0, j0)][map.coordinateToIndex(i1, j1)] = 1;
            }
    debug stderr.writefln("%(%(% 3d%)\n%)", distances);
    foreach (k; 0..distances.length)
        foreach (i; 0..distances.length)
            foreach (j; 0..distances.length)
                distances[i][j] = min(distances[i][j],
                        distances[i][k] + distances[j][k]);
    debug stderr.writefln("%(%(% 3d%)\n%)", distances);
    distances.joiner.array.sort!((a, b) => a > b).uniq.find!(a => a != inf).front.writeln;
}

struct Grid
{
    immutable size_t height, width;
    auto coordinates() const
    {
        return height.iota.cartesianProduct(width.iota);
    }
    auto coordinateToIndex(size_t i, size_t j) const
    {
        return i * width + j;
    }
    auto length() const
    {
        return height * width;
    }
}
unittest
{
    auto g = Grid(4, 5);
    assert (g.coordinates.map!(c => g.coordinateToIndex(c[0], c[1])).
            equal(g.length.iota));
    stderr.writeln("unittest passed!");
}
enum MapElement
{
    road, wall
}
struct Map
{
    Grid grid;
    MapElement[][] map;
    this (Grid grid)
    {
        this.grid = grid;
    }
    void addRow(string t)
    {
        with (MapElement)
            map ~= t.byChar.map!(c => ['.': road, '#': wall][c]).array;
        assert (map[$-1].length == width);
    }
    alias grid this;
}
