/**akshaykumar99**/
 
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;
 
template<typename T> using id_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update> ;
template<typename T> using id_setp = tree<pair<T,T>,null_type,less<pair<T,T>>,rb_tree_tag,tree_order_statistics_node_update> ;

#define f(i,x,n) for(i=x;i<n;i++)
#define fr(i,x,n) for(i=x;i>=n;i--)
#define pu push_back           
#define pp pop_back
#define F first
#define S second
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define SP(x) fixed<<setprecision(x)
#define IOS() ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
 
const long long MOD=1e9+7;
const long double PI = acos(-1);
const long long INF=INT_MAX;
const long long LINF=LLONG_MAX;
const long long N=1e5+1;
 
typedef long long ll;
typedef long double ld;
 
string s[30];
int h,w;
int dist[30][30];

bool poss(int i,int j){
   return i<h and j<w and i>=0 and j>=0 and s[i][j] == '.';
}
int main()
{
    IOS();
   cin >> h >> w;
      f(i,0,h){
         cin >> s[i];
      }
      int ans = 0;
      f(i,0,h)
      {
         f(j,0,w)
         {
            if(s[i][j] == '.')
            {
               set<array<int,3>> q;
               int mx = 0;
               q.insert({0,i,j});
               vector<vector<int>> dist(h,vector<int>(w,MOD));
               dist[i][j] = 0;
               while(!q.empty())
               {
                  auto v = *q.begin();
                  q.erase(q.begin());
                  int ff = v[1];
                  int ss = v[2];
                  vector<pii> itr = {{ff+1,ss},{ff-1,ss},{ff,ss+1},{ff,ss-1}};
                  for(auto &e : itr)
                  {
                     if(poss(e.F,e.S))
                     {
                        if(dist[ff][ss]+1<dist[e.F][e.S])
                        {
                           q.erase({dist[e.F][e.S],e.F,e.S});
                           dist[e.F][e.S] = dist[ff][ss]+1;
                           mx = max(mx,dist[e.F][e.S]);
                           q.insert({dist[e.F][e.S],e.F,e.S});
                        }
                     }
                  }
               }
               ans = max(ans,mx);
            }
         }
      }
      cout << ans << '\n';
      return 0;
   }
}