#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
#define fastio() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define pb push_back
#define F first
#define S second
#define nl cout<<"\n"
//cout<<fixed<<setprecision(11);
const ll MOD=1e9+7;
const ll ARR_MAX = 23;
const ll VAL_MAX = 1e5+1;
const ll INF=1e14;

string s[ARR_MAX];
int h,w;

bool ck(int x,int y){
    if(x>=0 && x<h && y>=0 && y<w && s[x][y]=='.'){
        return true;
    }
    return false;
}

void solve(){
    // int h,w;
    cin>>h>>w;
    // string s[h];
    for(int i=0;i<h;i++){
        cin>>s[i];
    }
    int mx=0;
    int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
    for(int i=0;i<h*w;i++){
        // int xi=get_x(i),yi=get_y(i);
        if(s[i/w][i%w]=='#') continue;
        priority_queue<pii> pq;
        pq.push({0,i});
        int n=h*w;
        int vis[n]={};
        int dist[n];
        while(!pq.empty()){
            int d=-pq.top().F;
            int node=pq.top().S;
            pq.pop();
            if(vis[node]){
                dist[node]=min(dist[node],d);
            }
            else{
                dist[node]=d;
            }
            vis[node]=1;
            int x=node/w,y=node%w;
            for(int j=0;j<4;j++){
                int xx=x+dx[j],yy=y+dy[j];
                int nxt=xx*w+yy;
                if(ck(xx,yy) && !vis[nxt]){
                    pq.push({-1*(d+1),nxt});
                }   
            }
        }
        for(int i=0;i<n;i++){
            // cout<<i/h<<" "<<i%h<<" "<<vis[i]<<" "<<dist[i],nl;
            if(vis[i])
                mx=max(mx,dist[i]);
        }
        // return;
        // cout<<i/h<<" "<<i%h<<" "<<mx,nl;
    }
    cout<<mx,nl;
}

int main(){
    fastio();
    int t=1;
    // cin>>t;
    while(t--){
        solve();
    }
    return 0;
}