#pragma GCC optimize("O3")
#pragma GCC target("avx")
#include <stdio.h>
#include <stdlib.h>
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define abs(a) ((a) > 0 ? (a) : (-1 * (a)))
#define rep(i, n) for ((i) = 0; (i) < (int)(n); (i)++)
#define rep2(i, s, e) for ((i) = (s); (i) < (int)(e); (i)++)

int path[25][25];
int map[25][25];
int x[500];
int y[500];
int x2[500];
int y2[500];

int main(void)
{

    int h, w, i, j, k, l, m, mx = 0;
    char buf[50];
    scanf("%d %d", &h, &w);
    rep(i, h)
    {
        scanf("%s", &buf);
        rep(j, w)
            map[i + 1][j + 1] = buf[j];
    }
    rep(i, h + 2) rep(j, w + 2) if (i == 0 || j == 0 || i == h + 1 || j == w + 1) map[i][j] = '#';

    rep(i, h + 2)
    {
        rep(j, w + 2)
        {
            if (map[i][j] == '#')
                continue;
            rep(k, h + 2) rep(l, w + 2) path[k][l] = 1000;
            int flg = 0;
            int lng = 0;
            int cue = 1;
            int cue2 = 0;
            x[0] = i;
            y[0] = j;
            path[i][j] = 0;
            while (cue != 0)
            {
                rep(k, cue)
                {
                    int c = path[x[k]][y[k]];
                    int u = path[x[k] - 1][y[k]];
                    int d = path[x[k] + 1][y[k]];
                    int l = path[x[k]][y[k] - 1];
                    int r = path[x[k]][y[k] + 1];
                    int mc = map[x[k]][y[k]];
                    int mu = map[x[k] - 1][y[k]];
                    int md = map[x[k] + 1][y[k]];
                    int ml = map[x[k]][y[k] - 1];
                    int mr = map[x[k]][y[k] + 1];
                    if (mu != '#')
                    {
                        if (c + 1 < u)
                        {
                            path[x[k] - 1][y[k]] = c + 1;
                            x2[cue2] = x[k] - 1;
                            y2[cue2] = y[k];
                            cue2++;
                        }
                    }
                    if (md != '#')
                    {
                        if (c + 1 < d)
                        {
                            path[x[k] + 1][y[k]] = c + 1;
                            x2[cue2] = x[k] + 1;
                            y2[cue2] = y[k];
                            cue2++;
                        }
                    }
                    if (ml != '#')
                    {
                        if (c + 1 < l)
                        {
                            path[x[k]][y[k] - 1] = c + 1;
                            x2[cue2] = x[k];
                            y2[cue2] = y[k] - 1;
                            cue2++;
                        }
                    }
                    if (mr != '#')
                    {
                        if (c + 1 < r)
                        {
                            path[x[k]][y[k] + 1] = c + 1;
                            x2[cue2] = x[k];
                            y2[cue2] = y[k] + 1;
                            cue2++;
                        }
                    }
                    /*printf("%d, %d, %d,[%d][%d]\n", i, j, k, x[k], y[k]);
                    rep(l, h + 2)
                    {
                        rep(m, w + 2)
                        {
                            printf("%d\t", path[l][m]);
                        }
                        printf("\n");
                    }*/
                }
                rep(k, cue2)
                {
                    x[k] = x2[k];
                    y[k] = y2[k];
                }
                cue = cue2;
                cue2 = 0;
            }
            rep(k, h + 2) rep(l, w + 2) mx = max(mx, path[k][l] * (map[k][l] == '.'));
        }
    }
    printf("%d", mx);

    return 0;
}


Measured memory_bytes: 128