#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
using namespace std;
using namespace __gnu_pbds;
typedef long long int ll;
 
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

 
 
const ll N = 100005;
const ll mod = 1000000007;
const long long int inf = 1e10+5;
#define pp pair<ll,ll>
 
typedef long double ld;
typedef vector<pp> vpl;
#define MP make_pair
#define endl "\n"
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep1(i,n) for(ll i=1;i<n;i++)
#define rrep(i,n) for(ll i=n-1;i>=0;i--)
#define repb(i,n) for(ll i=1;i<n-1;i++) 
#define trace(i,a) for(auto i=a.begin();i!=a.end();i++) 
#define mtrace(i,a) for(auto i=a.begin();i!=a.end();i++)  cout<<i->first<<" "<<i->second<<endl;   
void fastIO(void);
 
void decimal(int);
ll modmulti(ll, ll);
ll modadd(ll, ll);
ll modpower(ll, ll);
ll gcd(ll, ll );
ll modinv(ll);



ll a[20][20];
ll vis[20][20];
string s[20];
ll h,w;
void BFS(pp node, ll dist)
{
    queue<pair<pp,ll>> q;
    q.push({node,0});
    
    while(!q.empty()){
        ll x = q.front().first.first, y = q.front().first.second;
        vis[x][y] = 1;
        dist = q.front().second;
        q.pop();
        a[x][y] = dist;
        if(x-1>=0){
            if(s[x-1][y]=='.' && vis[x-1][y]==0){
                q.push({{x-1,y},dist+1});
            }
        }
        if(x+1<h){
            if(s[x+1][y]=='.' && vis[x+1][y]==0){
                q.push({{x+1,y},dist+1});
            }
        }
        if(y-1>=0){
            if(s[x][y-1]=='.' && vis[x][y-1]==0){
                q.push({{x,y-1},dist+1});
            }
        }
        if(y+1<w){
            if(s[x][y+1]=='.' && vis[x][y+1]==0){
                q.push({{x,y+1},dist+1});
            }
        }
    }
   // pp temp = {0,0};
    // if(node==temp){
    //     rep(i,h){
    //         rep(j,w) cout<<a[i][j]<<" ";
    //         cout<<endl;
    //     }
    // }

    
}
void solve(pp st, pp ed, ll &curr)
{
    rep(i,h){
        rep(j,w){ a[i][j] = inf; vis[i][j]=0;}
    }
    BFS(st,0);
    curr = 0;
    rep(i,h){
        rep(j,w){
            if(a[i][j]>1000000) continue;
            curr = max(curr,a[i][j]);
        }
    }
    //cout<<curr<<endl;
}
int main(){
   // fastIO();
  
    cin>>h>>w;
    rep(i,h) cin>>s[i];
    pp st,ed;
    ll ans = 0;
    ll curr = 0;
    rep(i,h){
        rep(j,w){
            if(s[i][j]=='#') continue;
                    curr = 0;
                    st = {i,j};
                    ed = {i,j};
                    solve(st,ed,curr);
                    ans = max(curr,ans);
        }
    }
    cout<<ans<<endl;
  






   

}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
void fastIO(void)
{  ios_base::sync_with_stdio(false);
   cin.tie(0);
   cout.tie(0);
}
 
void decimal(int n){
   cout<<fixed;
   cout<<setprecision(n);
}
ll modmulti(ll a, ll b){
   return ((a%mod)*1ll*(b%mod))%mod;
}
ll modadd(ll a, ll b){
   ll asdfgh =  ((a%mod)+(b%mod)+mod+mod)%mod;
   asdfgh = (asdfgh+mod)%mod;
   return asdfgh;
}
ll modpower(ll a, ll n){
   if(n==0) return 1;
   if(n==1) return a%mod;
   ll b = modpower(a,n/2);
   b = modmulti(b,b);
   if(n%2==0) return b;
   return modmulti(a,b);
}
ll gcd(ll a, ll b){
   if(b==0)
      return a;
   return gcd(b,a%b);
}
ll modinv(ll a){
   return modpower(a,mod-2);
}
 