#include <bits/stdc++.h>
using namespace std;
#define ll                      long long int
#define pb                      push_back
#define rep(i,a,b,c)            for(ll i=(a);i<=(b);i+=(c))
#define repb(i,a,b,c)           for(ll i=(a);i>=(b);i-=(c))
#define MOD                     1000000007
#define inf                     3e18
#define ld                      long double
//#define mp                      make_pair
#define vpll                    vector<pair<ll,ll>>
#define sll                     set<ll>
#define vll                     vector<ll>
#define vld                     vector<ld>
#define vvll                    vector<vector<ll>>
#define vvld                    vector<vector<ld>>
#define pll                     pair<ll,ll>
#define vvpll                   vector<vector<pair<ll,ll>>>
#define pqll                    priority_queue<ll>
#define mll                     map<ll,ll>
#define mlc                     map<ll,char>
#define um                      unordered_map
#define umll                    um<ll,ll>
#define umlc                    um<ll,char>
#define umcl                    um<char,ll>
#define all(x)                  x.begin(),x.end()
#define fi                      first
#define se                      second
#define ln                      cout<<"\n";
#define endl                    "\n"
#define test                    ll Testcases;cin>>Testcases;while(Testcases--)
#define isvowel(a)              (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u')
#define fastIO                  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define show(w,size)            {for(ll i=0;i<size;i++) cout<<w[i]<<" ";cout<<"\n";}
#define print(a)                cout<<a<<"\n";
#define mset(dp,no)             memset(dp,no,sizeof(dp))
#define input(a,n)              rep(i,0,n-1,1) cin>>a[i];
#define countbit                __builtin_popcount                                           //Number of setbits in decimal notation
#define lb(v,val)               lower_bound(all(v),val)-v.begin()
#define ub(v,val)               upper_bound(all(v),val)-v.begin()
#define SS                      stringstream
#define db(...)                 __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) { cerr << name << " : " << arg1 <<'\n'; }
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
    const char* comma = strchr(names + 1, ',');
    cerr.write(names, comma - names) << " : " << arg1 << " | "; __f(comma + 1, args...);
}

ll poww(ll b,ll e){if(e==0)return 1;else if(e%2==0){ll a=pow(b,e/2);return a*a;}else {ll a=pow(b,e/2);return b*a*a;}}
ll powm(ll x,ll y,ll m=MOD){x=x%m;ll res=1;while(y){if(y&1)res=res*x;res%=m;y=y>>1;x=x*x;x%=m;}return res;}
ll modInverse(ll a,ll m=MOD){if(m==1)return 0;ll m0=m,y=0,x=1;while(a>1){ll q=a/m,t=m;m=a%m,a=t;t=y;y=x-q*y;x=t;}if(x<0) x+=m0;return x;}

vector<vector<pll>> adj;
vll dis;

class Dijkstra
{
	public:
	void init(ll n)
	{
		dis.clear();
		dis.resize(n+1);
		rep(i,1,n,1)
			dis[i]=inf;
	}
	
	void find_dis(ll root)
	{
		dis[root]=0;
		set<pll> s;
		s.insert({0,root});
		while(!s.empty())
		{
			auto it=s.begin();
			ll val=(*it).se;
		//	db(val);
			s.erase(it);
			for(auto i:adj[val])
			{
				if(i.se+dis[val]<dis[i.fi])
				{
					s.erase({dis[i.fi],i.fi});
					dis[i.fi]=i.se+dis[val];
					s.insert({dis[i.fi],i.fi});
				}
			}
		}
	}
};


int main()
{
	fastIO
	ll r,c;
	cin>>r>>c;
	string s[r];
	input(s,r);
	map<pll,ll> mp;
	ll t=0;
	umll is;
	rep(i,0,r-1,1)
		rep(j,0,c-1,1)
		{
			mp[{i,j}]=++t;
			if(s[i][j]=='.')
			{
				is[t]=1;
			//	db(t,is[t]);
			}
		}
//	db(t);
	adj.resize(t+1);
	rep(i,0,r-1,1)
		rep(j,0,c-1,1)
			if(s[i][j]=='.')
			{
			//	db(s[i][j],i+1,mp[{i,j}],mp[{i+1,j}]);
				if(i+1<r)
				{
				//	db("h");
					if(s[i+1][j]=='.')
						adj[mp[{i,j}]].pb({mp[{i+1,j}],1});
				}
			//	db("h");
				if(i-1>=0)
				{
					//db("h");
					if(s[i-1][j]=='.')
						adj[mp[{i,j}]].pb({mp[{i-1,j}],1});
				}
			//	db("he");
				if(j+1<c)
				{
					if(s[i][j+1]=='.')
						adj[mp[{i,j}]].pb({mp[{i,j+1}],1});
				}
			//	db("her");
				if(j-1>=0)
				{
					if(s[i][j-1]=='.')
						adj[mp[{i,j}]].pb({mp[{i,j-1}],1});
				}
			//	db("here");
			//	db(i,j);
			}
	
	ll n=r*c;
	ll fa=0;
	Dijkstra d;
	rep(i,1,n,1)
		if(is[i])
		{
			d.init(n);
			d.find_dis(i);
			ll ans=0;
			rep(j,1,n,1)
			{
			//	db(i,j,dis[j]);
				if(is[j])
				{
				//	db(j);
					ans=max(dis[j],ans);
				}
			}
			fa=max(ans,fa);	
		}			
	cout<<fa;
				
	return 0;
}




Measured memory_bytes: 384