#include<bits/stdc++.h>
#define REP(i,n) for(int i = 0; i < n; i++)
#define rep(i, a, b) for(int i = a; i < b; i++)

using namespace std;
static const int N = 100;
static const int INF = 1e9;

int h , w;
int sy, sx, gy, gx;
int d[N][N];
bool used[N][N];
vector<string> S;

void bfs(int sh, int sw){
    queue<pair<int, int> > Q;
    for(int i = 0; i < h; i++) for(int j = 0; j < w; j++) used[i][j] = false;
	for(int i = 0; i < h; i++) for(int j = 0; j < h; j++) d[i][j] = INF;
  
    used[sh][sw] = true;
    d[sy][sx] = 0;
    Q.push(make_pair(sy, sx));//全てはスタート地点をqueueに突っ込んでからは閉まる
    while(!Q.empty()){
        pair<int,int> u = Q.front();Q.pop();
        int th = u.first, tw = u.second;
        used[th][tw] = true;
        if(th + 1 < h && !used[th+1][tw] && S[th+1][tw] == '.'){
            Q.push(make_pair(th+1,tw));
            used[th+1][tw] = true;
            d[th+1][tw] = d[th][tw] + 1;
        }
        if(th - 1 >= 0 && !used[th - 1][tw] && S[th-1][tw] == '.'){
            Q.push(make_pair(th-1,tw));
            used[th - 1][tw] = true;
            d[u.first - 1][tw] = d[th][tw] + 1;
        }
        if(tw + 1 < w && !used[th][tw+1] && S[th][tw+1] == '.'){
            Q.push(make_pair(th,tw+1));
            used[th][tw+1] = true;
            d[u.first][tw+1] = d[th][tw] + 1;
        }
        if(tw - 1 >= 0 && !used[th][tw-1] && S[th][tw-1] == '.'){
            Q.push(make_pair(th,tw-1));
            used[th][tw-1] = true;
            d[u.first][tw-1] = d[th][tw] + 1;
        }
    }
  	int ans = 0;
  	rep(i, 0, h) rep(j, 0, w) if(d[i][j] != INF) ans = max(ans, d[i][j]);
}
int main(){
    cin >> h >> w;
    S.resize(h);
    for(int i = 0; i < h; i++) cin >> S[i];
  
  	int ans = 0;
    for(int i = 0; i < h; i++) for(int j = 0; j < h; j++) d[i][j] = INF;
    for(int i = 0; i < h; i++)for(int j = 0; j < w; j++) if(S[i][j] =='.'){
    	ans = max(bfs(i, j), ans);
    }
    cout << ans << endl;

}
