#include <iostream>
#include <math.h>
#include <queue>
using namespace std;

typedef long long ll;
#define rep(i, n) for(long long i = 0; i < (long long)(n); i++)
#define memset(v, h) memset((v), h, sizeof(v))
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};

ll m[20][20];

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

struct node
{
    public: ll x;
    public: ll y;

    node(ll xx, ll yy)
    {
        x = xx;
        y = yy;
    }
};

long long resolve(ll h, ll w, ll sx, ll sy, ll gx, ll gy)
{
    ll dist[h][w];
    bool get[h][w];
    rep(i,h)rep(j,w)dist[i][j]=10000;
    rep(i,h)rep(j,w)get[i][j]=false;
    queue<node> que;

    dist[sx][sy] = 0;
    get[sx][sy] = true;
    node n = {sx, sy};
    que.push(n);

    while (!que.empty()) {
        node v = que.front();
        que.pop();

        ll qx = v.x;
        ll qy = v.y;

        get[qx][qy] = true;

        if(qx == gx && qy == gy)
        {
            return dist[gx][gy];
        }

        if(qx > 0)
        {
            if(m[qx-1][qy] == 0 && dist[qx-1][qy] == 10000)
            {
                if(dist[qx-1][qy] > dist[qx][qy] + 1)
                {
                    dist[qx-1][qy] = dist[qx][qy] + 1;
                }

                if(!get[qx-1][qy])
            {
                que.push({qx-1, qy});
            }
            }
        }

        if(qx < h - 1)
        {
            if(m[qx+1][qy] == 0 && dist[qx+1][qy] == 10000)
            {
                if(dist[qx+1][qy] > dist[qx][qy] + 1)
                {
                    dist[qx+1][qy] = dist[qx][qy] + 1;
                }

                if(!get[qx+1][qy])
            {
                que.push({qx+1, qy});
            }
            }
        }

        if(qy > 0)
        {
            if(m[qx][qy-1] == 0  && dist[qx][qy-1] == 10000)
            {
                if(dist[qx][qy-1] > dist[qx][qy] + 1)
                {
                    dist[qx][qy-1] = dist[qx][qy] + 1;
                }

                if(!get[qx][qy-1])
            {
                que.push({qx, qy-1});
            }
            }
        }

        if(qy < w - 1)
        {
            if(m[qx][qy+1] == 0  && dist[qx][qy+1] == 10000)
            {
                if(dist[qx][qy+1] > dist[qx][qy] + 1)
                {
                    dist[qx][qy+1] = dist[qx][qy] + 1;
                }

                if(!get[qx][qy+1])
            {
                que.push({qx, qy+1});
            }
            }
        }
    }

    return dist[gx][gy];
}

int main(){
    ll h, w;
    ll v = 1;
    cin >> h >> w;

    rep(i, 20)rep(j, 20) m[i][j] = -1;

    rep(i,h){
        rep(j,w)
        {
            char l;
            cin >> l;
            if(l == '.')
            {
                m[i][j] = 0;
            }
            else
            {
                m[i][j] = -1;
            }
        }
    }
    
    rep(sx,h){
        rep(sy,w){
            rep(gx, h){
                rep(gy, w)
                {
                    if(sx == gx && sy == gy)
                    {
                        continue;
                    }

                    if(m[sx][sy] != 0 || m[gx][gy] != 0)
                    {
                        continue;
                    }

                    ll f = resolve(h, w, sx, sy, gx, gy);
                    if(f > v)
                    {
                        v = f;
                    }
                }
            }
        }
    }

    cout << v << endl;
    return 0;
}

Measured memory_bytes: 384