/****************************************************

@author: vichitr
Compiled On: 10th Jan 2020

*****************************************************/
#include<bits/stdc++.h>
#define MAX 9223372036854775807
#define endl "\n"
#define ll long long
#define int long long
#define double long double
#define pb push_back
#define pf pop_front
#define mp make_pair
#define ip pair<int, int>
#define F first
#define S second

#define loop(i,n) for(int i=0;i<n;i++)
#define loops(i,s,n) for(int i=s;i<=n;i++)
#define fast ios::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL)
using namespace std;

const ll MOD = 1e9+7;
const ll SZ = 107;
const ll N = 1e6+7;
// const ll M = 2e5+7;

ll pwr(ll x, ll y)
{
    ll r = 1LL;
    while(y)
    {
        if(y&1)
            r = (r * x) % MOD;
        y >>= 1;
        x = (x * x) % MOD;
    }
    return r;
}

int inv(int x)
{
    return pwr(x, MOD-2ll);
}

int fact[N];

int nCr(int x, int y){
    int ans= fact[x];
    ans *= inv(fact[y]);
    ans %= MOD;
    ans *= inv(fact[x-y]);
    ans %= MOD;
    return ans;
}

string a[21];
int n, m;

void solve()
{ 
    cin>>n>>m;
    loop(i, n) cin>>a[i];
    // memset(dp, -1, sizeof dp);
    int ans = 0;
    loop(i, n){
        loop(j, m){
            if(a[i][j]=='#') continue;

            int d[n][m];
            bool vis[n][m];
            memset(vis, 0, sizeof vis);
            loop(ii, n) loop(jj, m) d[ii][jj] = 1e6;
            queue<ip> q;
            q.push({i, j});
            d[i][j] = 0;
            while(!q.empty()){
                ip p = q.front();
                q.pop();
                int x = p.F, y = p.S;
                ans = max(ans, dp[x][y]);
                if(x-1 >= 0 and !vis[x-1][y] and a[x-1][y]=='.'){

                    vis[x-1][y] = 1;
                    d[x-1][y] = 1+d[x][y];
                    // ans = max(ans, )
                    q.push({x-1, y});
                }
                if(x+1 < n and !vis[x+1][y] and a[x+1][y]=='.'){
                    vis[x+1][y] = 1;
                    d[x+1][y] = 1+d[x][y];
                    q.push({x+1, y});
                }
                if(y-1 >= 0 and !vis[x][y-1] and a[x][y-1]=='.'){
                    vis[x][y-1] = 1;
                    d[x][y-1] = 1+d[x][y];
                    q.push({x, y-1});
                }
                if(y+1 < m and !vis[x][y+1] and a[x][y+1]=='.'){
                    vis[x][y+1] = 1;
                    d[x][y+1] = 1+d[x][y];
                    q.push({x, y+1});
                }
            }

            // loop(ii, n) loop(jj, m){
            //     if(a[ii][jj]=='.')
            //         ans = max(ans, d[ii][jj]); 
            // }
            
        }
    }
    cout<<ans<<endl;
}

signed main()
{
    fast;
    int t=1;
    // cin >>t;

    // fact[0] =1;
    // for(int i=1;i<N;i++){
    //     fact[i] = fact[i-1]*i;
    //     fact[i] %= MOD;
    // }

    while(t--){
        solve();
        
    }
    return 0;
}

/*****************************

3 595

43 2

300 4

554 10


***************************/