#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
//#include <ext/pb_ds/detail/standard_policies.hpp>
#define ll long long
#define ld long double
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define vll vector<ll>
#define pll pair<ll,ll>
#define int long long
using namespace std;
using namespace __gnu_pbds;



typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>
ordered_set;
// ordered_set x;
// x.insert(a)
// *(x.find_by_order(k)) -> k th largest element in the set
// x.order_of_key(k) -> number of elements < k

const ll N = 3e5+100;
const ll MOD = 1e9+7;
const ll INF = 1e18;


long long binpow(long long a, long long b, long long m=MOD) {
     a %= m;
     long long res = 1;
     while (b > 0) {
         if (b & 1)
             res = res * a % m;
         a = a * a % m;
         b >>= 1;
     }
     return res;
 }

int n,m;
char grid[21][21];

ll solve(ll i,ll j,ll x,ll y){
    ll dis[n+1][m+1];
    for(int ii =1;ii<=n;ii++){
        for(int jj =1;jj<=m;jj++){
            dis[ii][jj] = INF;
        }
    }
    dis[i][j] = 0;
    queue<pll> q;
    q.push(mp(i,j));
    while(!q.empty()){
        pll p=  q.front();
        q.pop();
        vll dx = {-1,1};
        vll dy = {-1,1};
        for(int l = 0;l<2;l++){
            if((p.f-dx[l])>=1 && (p.f-dx[l])<=n && dis[p.f-dx[l]][p.s]> (dis[p.f][p.s]+1) && grid[p.f-dx[l]][p.s]!='#'){
                dis[p.f-dx[l]][p.s]=dis[p.f][p.s]+1;
                q.push(mp(p.f-dx[l],p.s));
            }
        }
        for(int l = 0;l<2;l++){
            if((p.s-dy[l])>=1 && (p.s-dy[l])<=m && dis[p.f][p.s-dy[l]] > (dis[p.f][p.s]+1) && grid[p.f][p.s-dy[l]]!='#'){
                dis[p.f][p.s-dy[l]]=dis[p.f][p.s]+1;
                q.push(mp(p.f,p.s-dy[l]));
            }
        }
           
    }
    if(dis[x][y] == INF) return -2;
    else return dis[x][y];
}

signed main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(nullptr);
    
    cin>>n>>m;

    for(int i =1;i<=n;i++){
        for(int j =1;j<=m;j++){
            cin>>grid[i][j];
        }
    }
    ll ans = 0;
    for(int i =1;i<=n;i++){
        for(int j =1;j<=m;j++){
            for(int x =1;x<=n;x++){
                for(int y = 1;y<=m;y++){
                    if(grid[i][j] == '.' && grid[x][y] == '.' && (i!=x || y != j)){
                      ans =max(ans,  solve(i,j,x,y));
                    }
                }
            }
        }
    }
    cout<<ans<<endl;

}   