#include <bits/stdc++.h>
using namespace std;
#define rep(i, s, n) for (int i = (s); i < (int)(n); i++)
#define all(v) v.begin(), v.end()
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; }
using ll = long long;
const ll mod = 1e9+7; int INF=INT_MAX; ll LLINF = 1LL << 60;
const vector<int> d8x = {1, 0, -1, 0, 1, -1, -1, 1}; vector<int> d8y = {0, 1, 0, -1, 1, 1, -1, -1};
const vector<int> d4x = {1, 0, -1, 0}; vector<int> d4y = {0, 1, 0, -1};

//

ll h,w;
vector<vector<char>> maze(21,vector<char>(21));
vector<vector<ll>> dist(21,vector<ll>(21));
vector<vector<bool>> seen(21,vector<bool>(21));

int bfs(ll s1, ll s2){
    rep(i,0,h)rep(j,0,w){
        dist[i][j]=-INF;
        seen[i][j]=false;
    }
    queue<pair<ll,ll>> que;
    dist[s1][s2]=0;
    que.push({s1,s2});
    while(!que.empty()){
        pair<ll,ll> p = que.front();
        que.pop();
        ll y=p.first;
        ll x=p.second;
        seen[y][x]=true;
        rep(i,0,4){
            ll nx=x+d4x[i];
            ll ny=y+d4y[i];
            if(0<=ny&&ny<h&&0<=nx&&nx<w&&(seen[ny][nx]==false)&&(maze[ny][nx]!='#')){
                que.push({ny,nx});
                dist[ny][nx]=dist[y][x]+1;
            }
        }
    }
    ll temp=0;
    rep(i,0,h)rep(j,0,w) temp=max(temp,dist[i][j]);
    return temp;
}


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