#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
constexpr int di[] = { 0, 1, 0, -1 }, dj[] = { 1, 0, -1, 0 };
#define rep(i, n) for (int i = 0; i < n; i++)
#define repr(i, n) for (int i = n; i >= 0; i--)
#define SORT(v) sort((v).begin(), (v).end())
#define SORTR(v) sort((v).rbegin(), (v).rend())
#define all(v) (v).begin(), (v).end()
#define N 100005
constexpr ll inf = 100000000000000;
/*cout<<fixed<<setprecision(20);cin.tie(0);ios::sync_with_stdio(false);*/
int h,w;
vector<string> s;
vector<vector<int>> maze;
bool check(int mid){

  return false;
}

ll serch(ll ok,ll ng) {
	while (abs(ok-ng) > 1) {
		ll mid = (ok + ng) / 2;
		if (check(mid))ok = mid;
		else ng = mid;
	}
	return ok;
}
int bfs(int x,int y){
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      maze[i][j]=0;
    }
  }
  int ma;
  s[x][y]='#';
  queue<P> q;
  q.push(make_pair(x,y));
  while(!q.empty()){
  for(int i=0;i<4;i++){
    auto nq=q.front();q.pop;
    int nx=x+di[i];
    int ny=y+dj[i];
    if(0<=nx&&nx<h&&0<=ny&&ny<w&&s[nx][ny]=='.'){
      q.push(make_pair(nx,ny));
      maze[nx][ny]=maze[x][y]+1;
    }
  }
  }
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      ma=max(ma,maze[i][j]);
    }
  }
  return ma;
}

int main(){
  cin>>h>>w;
  s.resize(h);
  maze.resize(h);
  for (int i = 0; i < h; i++){
      cin>>s[i];
      maze[i].resize(w);
      for(int j=0;j<w;j++){
         maze[i][j]=0;
      }
  }
  int ans=0;
  for (int i = 0; i < h; i++){
      for(int j=0;j<w;j++){
         if(s[i][j]!='#'){
           ans=max(ans,bfs(i,j));
         }
      }
  }
  cout<<ans<<endl;
}

