#include<bits/stdc++.h>
using namespace std;
using ll  = long long;
using vl  = vector<ll>;
using vi  = vector<int>;
#define _GLIBCXX_DEBUG
#define IO_STREAM cin.tie(0);ios::sync_with_stdio(false)
#define all(x) x.begin(),x.end()
#define rep(i,sta,end) for(int i=sta;i<end;++i)
#define lcm(a,b) (a)/__gcd((a),(b))*(b)
#define pb push_back
const ll INF = 1000000000000000;
const ll MOD = 1000000007;
const double PI = acos(-1);
//||
#define DBG(a,b,c,d) //cout<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<endl
//DBG("","","","");

signed main(){
	IO_STREAM;
	int H,W;
	cin>>H>>W;
	int m[H+2][W+2]={0};
	queue<pair<int,int>> start;
	char c;
	pair<int,int> p;
	rep(i,1,H+1){
		rep(j,1,W+1){
			cin>>c;
			if(c=='.'){
				m[i][j]=1;
				p.first=i;
				p.second=j;
				start.push(p);
			}
		}
	}
	int ans=0;
	while(!start.empty()){
		pair<int,int>st=start.front();start.pop();
		queue<pair<int,int>> q;

		q.push(st);
		int cnt[H+2][W+2]={0};
		while(!q.empty()){
			int pre_h,pre_w;
			pair<int,int> next;
			pair<int,int> v=q.front();q.pop();
			pre_h = v.first;
			pre_w = v.second;
			if(m[pre_h+1][pre_w]==1&&cnt[pre_h+1][pre_w]==0){
				next.first =pre_h+1;
				next.second=pre_w;
				cnt[pre_h+1][pre_w]=cnt[pre_h][pre_w]+1;
				ans=max(ans,cnt[pre_h+1][pre_w]);
				q.push(next);
			}
			if(m[pre_h-1][pre_w]==1&&cnt[pre_h-1][pre_w]==0){
				next.first =pre_h-1;
				next.second=pre_w;
				cnt[pre_h-1][pre_w]=cnt[pre_h][pre_w]+1;
				ans=max(ans,cnt[pre_h-1][pre_w]);
				q.push(next);
			}
			if(m[pre_h][pre_w+1]==1&&cnt[pre_h][pre_w+1]==0){
				next.first =pre_h;
				next.second=pre_w+1;
				cnt[pre_h][pre_w+1]=cnt[pre_h][pre_w]+1;
				ans=max(ans,cnt[pre_h][pre_w+1]);
				q.push(next);
			}
			if(m[pre_h][pre_w-1]==1&&cnt[pre_h][pre_w-1]==0){
				next.first =pre_h;
				next.second=pre_w-1;
				cnt[pre_h][pre_w-1]=cnt[pre_h][pre_w]+1;
				ans=max(ans,cnt[pre_h][pre_w-1]);
				q.push(next);
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}
