#include<cstdio>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<deque>
#include<queue>
#include<tuple>
#include<algorithm>
#include<numeric>
#include<limits>
#include<boost/multiprecision/cpp_int.hpp>
using namespace std;
using namespace boost::multiprecision;
#define BEGIN ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define END return EXIT_SUCCESS
#define rep(I,N) for(auto I=0;I<(N);++I)
#define up(I,A,B) for(auto I=(A);I<=(B);++I)
#define dw(I,A,B) for(auto I=(A);I>=(B);--I)
#define all(C) (C).begin(),(C).end()
#define rall(C) (C).rbegin(),(C).rend()
#define ft first
#define sd second
#define mp make_pair
#define mt make_tuple
#define pf push_front
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define rs resize
typedef long long ll;
typedef unsigned long long ull;
template<class T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
template<class T>inline void                                      in(T &p){cin>>p;}
template<class T1,class T2>inline void                            in(T1 &p1,T2 &p2){cin>>p1>>p2;}
template<class T1,class T2,class T3>inline void                   in(T1 &p1,T2 &p2,T3 &p3){cin>>p1>>p2>>p3;}
template<class T1,class T2,class T3,class T4>inline void          in(T1 &p1,T2 &p2,T3 &p3,T4 &p4){cin>>p1>>p2>>p3>>p4;}
template<class T1,class T2,class T3,class T4,class T5>inline void in(T1 &p1,T2 &p2,T3 &p3,T4 &p4,T5 &p5){cin>>p1>>p2>>p3>>p4>>p5;}
template<class T>inline void                                      ins(T &p){for_each(all(p),in<decltype(p[0])>);}
template<class T>inline void                             out(T p){cout<<p<<endl;}
template<class T1,class T2>inline void                   out(T1 p1,T2 p2){cout<<p1<<" "<<p2<<endl;}
template<class T1,class T2,class T3>inline void          out(T1 p1,T2 p2,T3 p3){cout<<p1<<" "<<p2<<" "<<p3<<endl;}
template<class T1,class T2,class T3,class T4>inline void out(T1 p1,T2 p2,T3 p3,T4 p4){cout<<p1<<" "<<p2<<" "<<p3<<" "<<p4<<endl;}
inline                                              void out(double p){printf("%.10f\n",p);}
template<class T>inline                             void outs(T p){for_each(all(p),out<decltype(p[0])>);}
template<class T>inline void outs(vector<T> V){int n=V.size();rep(i,n)cout<<V[i]<<" \n"[i==n-1];}
typedef pair<int,int>P;
const int INF=1<<30;
const int N=30;
int d[N][N];
int di[4]={0,0,1,-1};
int dj[4]={1,-1,0,0};
int H,W;
int ans;
vector<string>S;
int bfs(int si,int sj,int gi,int gj){
  queue<P>q;
  for(int i=0;i<N;i++)for(int j=0;j<N;j++)d[i][j]=INF;
  d[si][sj]=0;
  q.push(P(si,sj));
  while(q.size()){
    P p=q.front();q.pop();
    if(p.ft==gi && p.sd==gj)break;
    for(int k=0;k<4;k++){
      int ni=p.ft+di[k];
      int nj=p.sd+dj[k];
      if(ni>=0 && ni<H && nj>=0 && nj<W && S[ni][nj]!='#' && d[ni][nj]==INF){
        q.push(P(ni,nj));
        d[ni][nj]=d[p.ft][p.sd]+1;
      }
    }
  }
  return d[gi][gj];
}
inline void solve(void){
  in(H,W);
  S.resize(H);ins(S);
  rep(i,H){
    rep(j,W){
      rep(k,H){
        rep(l,W){
          if(S[i][j]!='#'&&S[k][l]!='#'){
            chmax(ans,bfs(i,j,k,l));
          }
        }
      }
    }
  }
  out(ans);
}
int main(int argc,char**argv){
  BEGIN;
  solve();
  END;
}


Measured memory_bytes: 256