#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1LL<<60;
#define all(x) (x).begin(),(x).end()
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,k,n) for(int i=(k);i<(n);++i)

int main() {
    int H,W; cin >> H >> W;
    vector<string> maze(H);
    REP(i,H) cin >> maze[i];
    int K = H*W;
    ll G[K][K];
    REP(i,K){
        REP(j,K) G[i][j] = INF;
        G[i][i] = 0;
    }
    vector<int> di = {1,0,-1,0}, dj = {0,1,0,-1};
    REP(i,H)REP(j,W){
        if(maze[i][j]=='#') continue;
        REP(k,4) {
            int ni = i + di[k];
            int nj = j + dj[k];
            if(0<=ni && ni<H && 0<=nj && nj<W && maze[ni][nj]=='.') G[W*i+j][W*ni+nj] = 1;
        }
    }
    REP(k,K)REP(i,K)REP(j,K) G[i][j] = min(G[i][j],G[i][k]+G[k][j]);
    ll ans = 0;
    REP(i,K)REP(j,K) {
        if(maze[i/W][i%W]=='.'&& maze[j/W][j%W]=='.' && G[i][j]!=INF) ans = max(ans,G[i][j]);
    }
    cout << ans << endl;
  //REP(i,K){REP(j,K)cout<<G[i][j]<<" ";cout<<endl;}cout<<endl;
  return 0;
}