#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 int inf = 1e9+7;
/*cout<<fixed<<setprecision(20);cin.tie(0);ios::sync_with_stdio(false);*/
vector<vector<int>> dist;
vector<vector<char>> maze;
int h,w;
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){
  rep(i,h){
    rep(j,w){
      dist[i][j]=inf;
    }
  }
  dist[x][y]=0;
  queue<P> q;
  q.push(make_pair(x,y));
  while(!q.empty()){
    P nq=q.front();q.pop();
    rep(i,4){
      int nx=nq.first+di[i];
      int ny=nq.second+dj[i];
      if(0<=nx&&nx<h&&0<=ny&&ny<w&&maze[nx][ny]!='#'&&dist[nx][ny]==inf){
        q.push(make_pair(nx,ny));
        dist[nx][ny]=dist[nq.first][nq.second]+1;
      }
    }
  }
  int m=0;
  rep(i,h){
    rep(j,w){
      if(maze[i][j]=='.'&&dist[i][j]==inf){
        m=max(m,dist[i][j]);
      }
    }
  }
  return m;
}

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

