#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;

#define ll long long int
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define all(a) a.begin(),a.end()
ll n, m;
map<pair<ll, ll>, ll> node;
bool valid(ll x, ll y) {
	if(x < n && x >=0 && y < m && y >= 0) {
		return true;
	}
	return false;
}
ll dist[401][401];
int main(void)
{
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll i, j, k, x, y, num = 0, ans = 0, l;
    cin>>n>>m;;
    string s[n];
    for(i=0; i<21; i++) {
    	for(j=0; j<21; j++) {
    		if(i == j) {
    			dist[i][j] = 0;
    		} 
    		else {
    			dist[i][j] = 1e9;
    		}
    	}
    }
    for(i=0; i<n; i++) {
    	cin>>s[i];
    	for(j=0; j<m; j++) {
    		if(s[i][j] == '.') {
    			node[mp(i, j)] = num++;
    		}
    	}
    }

    for(i=0; i<n; i++) {
    	for(j=0; j<m; j++) {
    		if(s[i][j] == '#') {
    			continue;
    		}
    		for(l = 1; l>=0; l--) {
    			for(k=0; k<=1; k++) {
    				if(abs(l) == abs(k)) {
    					continue;
    				}
    				if(!valid(i + l, j + k)) {
    					continue;
    				}
    				x = i + l;
    				y = j + k;
    				if(s[x][y] == '#') {
    					continue;
    				}
    				dist[node[mp(i, j)]][node[mp(x, y)]] = 1;
    				dist[node[mp(x, y)]][node[mp(i, j)]] = 1;

    			}
    		}
    	}
    }
    for(i=k=0; k<num; k++) {
    	for(i=0; i<num; i++) {
    		for(j=0; j<num; j++) {
    			dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
    		}
    	}
    }
    for(i=0; i<num; i++) {
    	for(j=0; j<num; j++) {
    		if(dist[i][j] < 1e9) {
    			ans = max(ans, dist[i][j]);
    		}
    	}
    }
    cout<<ans<<"\n";
}