/*
    Don't practice until you get it right. Practice until you can't get it wrong.
*/
 
#include<bits/stdc++.h>
using namespace std;
 
#define ll long long int
#define ld double
#define pii pair<ll,ll>
#define vl vector<ll>
#define vb vector<bool>
#define vs vector<string>
#define vp vector<pii>
#define pb push_back
#define mp make_pair
#define sc(a) scanf("%lld",&a);
#define sd(a) scanf("%lf",&a);
#define test() ll tt;cin>>tt;for(ll testcase=1;testcase<=tt;testcase++)
#define all(v) v.begin(),v.end()
#define vivek_ghosh ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define MAX 1000055
#define mod 1000000007
#define ff first
#define ss second
// const int INF=0x3f3f3f3f;
 
ll power(ll x,ll n,ll M)
{
    if(n==0)
        return 1;
    else if(n%2 == 0)
        return power((x*x)%M,n/2,M);
    else
        return (x*power((x*x)%M,(n-1)/2,M))%M;
}
 
ll modinv(ll a,ll m)
{
    ll g =__gcd(a, m);
    ll res=power(a, m-2, m);
    return res;
}
 
vb prime(MAX,true);
vl prm;
void sieve()
{
	prime[0] = prime[1] = false;
	for(ll p=2;p*p<MAX;p++)
	{
		if(prime[p])
		{
			for(ll i=p*p;i<MAX;i+=p)
				prime[i] = false;
		}
	}
	for(ll p=2;p<MAX;p++)
	{
		if(prime[p])
			prm.pb(p);
	}
}

ll n,m,t,i,j,k,q,x,y,ans=0,cnt=0,sum=0,mx=-1,mn=INT_MAX;
string s;

int main()
{
	vivek_ghosh;
	
	ll h,w;
	cin>>h>>w;
	vs matrix(h);
	vp road;
	
	ll INF = (h*w)+10;
	
	vector<vl> grid(h,vl(w,0));
	map<pair<pii,pii>,ll> cost;
	for(i=0;i<h;i++)
	{
		for(j=0;j<w;j++)
		{
			for(ll k=0;k<h;k++)
			{
				for(ll l=0;l<w;l++)
				{
					pii start = {i,j};
					pii end = {k,l};
					if(start == end)
					{
						cost[{start,end}] = 0;
					}
					else
					{
						cost[{start,end}] = INF;
					}
				}
			}
		}
	}
	
	for(i=0;i<h;i++)
	{
		cin>>matrix[i];
		for(j=0;j<w;j++)
		{
			if(matrix[i][j] == '.')
			{
				road.pb(mp(i,j));
				grid[i][j] = 1;
			}
			else
				grid[i][j] = 0;
		}
	}
	
	for(i=0;i<h;i++)
	{
		for(j=0;j<w;j++)
		{
			if(grid[i][j] == 1)
			{
				pii start = mp(i,j);
				pii end;
				if(i>0 && grid[i-1][j] == 1)
				{
					end = mp(i-1,j);
					cost[mp(start,end)] = 1;
					cost[mp(end,start)] = 1;
					ans = 1;
				}
				if(i<h-1 && grid[i+1][j] == 1)
				{
					end = mp(i+1,j);
					// cout<<start.ff<<"  "<<start.ss<<endl;
					// cout<<end.ff<<"  "<<end.ss<<endl;
					cost[mp(start,end)] = 1;
					cost[mp(end,start)] = 1;
					ans = 1;
				}
				if(j>0 && grid[i][j-1] == 1)
				{
					end = mp(i,j-1);
					// cout<<start.ff<<"  "<<start.ss<<endl;
					// cout<<end.ff<<"  "<<end.ss<<endl;
					cost[mp(start,end)] = 1;
					cost[mp(end,start)] = 1;
					ans = 1;
				}
				if(j<w-1 && grid[i][j+1] == 1)
				{
					end = mp(i,j+1);
					// cout<<start.ff<<"  "<<start.ss<<endl;
					// cout<<end.ff<<"  "<<end.ss<<endl;
					cost[mp(start,end)] = 1;
					cost[mp(end,start)] = 1;
					ans = 1;
				}
				// cout<<endl;
			}
		}
	}
	
	ans = -1;
	
	ll roads = int(road.size());
	
	cnt = h*w;
	
	while(cnt > min(h*w-10,0ll))
	{
	for(ll i=0;i<h;i++)
	{
		for(ll j=0;j<w;j++)
		{
			for(ll k=0;k<h;k++)
			{
				for(ll l=0;l<w;l++)
				{
					if((grid[i][j] == 1) && (grid[k][l] == 1))
					{
						for(ll r=0;r<h;r++)
						{
							for(ll c=0;c<w;c++)
							{
								pii start = mp(i,j);
								pii end = mp(k,l);
								pii through = mp(r,c);
								if((start != end) && (start != through) && (end != through))
								{
									ll temp = 0;
									if(cost[{start,through}] != INF)
									{
										temp += cost[{start,through}];
									}
									else
									{
										temp = INF;
									}
									// cout<<"Temp1 = "<<temp<<endl;
									if(temp!=INF && cost[{through,end}] != INF)
									{
										temp += cost[{through,end}];
									}
									else
									{
										temp = INF;
									}
									// cout<<"Temp2 = "<<temp<<endl;
									
									// cout<<start.ff<<" "<<start.ss<<endl;
									// cout<<through.ff<<"  "<<through.ss<<endl;
									// cout<<end.ff<<"  "<<end.ss<<endl;
									// cout<<"COST = "<<temp<<endl<<endl;
									
									if(temp != INF)
									{
										cost[{start,end}] = min(cost[{start,end}],temp);
										// cout<<"FINAL COST = "<<temp<<endl<<endl;
										// if(cost[{start,end}] != INF)
										// 	ans = max(ans,cost[{start,end}]);
									}
								}
							}
						}
					}
				}
			}
		}
	}
	cnt--;
	}
	
	ans = -1;
	
	for(i=0;i<h;i++)
	{
		for(j=0;j<w;j++)
		{
			for(ll k=0;k<h;k++)
			{
				for(ll l=0;l<w;l++)
				{
					pii start = {i,j};
					pii end = {k,l};
					if(cost[{start,end}] != INF)
					{
						ans = max(ans,cost[{start,end}]);
					}
				}
			}
		}
	}
	
	cout<<ans<<endl;
 
	return 0;
}

