#include <bits/stdc++.h>
#define ll long long
using namespace std;
using Graph=vector<vector<int>>;

const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
bool seen[30][30];
string vec[25];
int ans[30][30];
int h,w;
void dfs(int a,int b){
  seen[a][b]=true;
  for(int dir=0;dir<4;dir++){
    int nh=a+dx[dir];
    int nw=b+dy[dir];
    if(nh<0||nh>=h||nw<0||nw>=w) continue;
    if(vec[nh][nw]=='#')continue;
    if(seen[nh][nw]==true) continue;
    ans[nh][nw]=min(ans[nh][nw],ans[a][b]+1);
    dfs(nh,nw);
  }
}
 
ll gcd(ll a, ll b){
  if(b == 0){
    return a;
  }
  else{
    return gcd(b,(a%b));
  }
}
ll lcm(ll a,ll b){
  return a/gcd(a,b)*b;
}
ll mpower(ll a,ll b,ll c){
  int z;
  if(b==0){
    z=1;
    z%=c;
    return z;
  }
  if(b==1){
    z=a;
    z%=c;
    return z;
  }
  else{
    return (((mpower(a,b/2,c))*(mpower(a,b/2,c))%c)*mpower(a,b%2,c)%c);
  }
}

int main(){
  cin>>h>>w;
  for(int i=0;i<h;i++){
    cin>>vec[i];
  }
  int a,b;
  int answer=0,p=0;
  for(int i=0;i<h*w;i++){
    a=i/w,b=i%w;
    if(vec[a][b]=='.'){
      memset(seen,0,sizeof(seen));// seen 配列全体を false に初期化
      fill(ans,ans+h*w,10000000);// ans 配列全体を 0 に初期化
      dfs(a,b);
      for(int j=0;j<h;j++){
        for(int k=0;k<w;k++){
          if(vec[j][k]=='.'){
            answer=max(answer,ans[j][k]);
          }
        }
      }
    }
  }
  cout<<answer<<endl;
}
