#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define int ll
#define rep(i,n) for(int i=0;i<n;i++)
#define all(in) in.begin(), in.end()
#define INF (sizeof(int) == 4 ? (int)1e9:(int)1e18)
#define EPS 0.0000000001
template<class T, class S> void cmin(T &a, const S &b) { if (a > b)a = b; }
template<class T, class S> void cmax(T &a, const S &b) { if (a < b)a = b; }
template<typename Head, typename Value> auto vectors(const Head &head, const Value &v) { return vector<Value>(head, v); }
template<typename Head, typename... Tail> auto vectors(Head x, Tail... tail) { auto inner = vectors(tail...); return vector<decltype(inner)>(x, inner); }
using ld  = long double;
using pii = pair<int,int>;
using piii = pair<int,pii>;
int W,H;
int dx[]={0,0,1,-1}, dy[]={1,-1,0,0};
bool valid(int x,int y){return (0<=x&&x<W)&&(0<=y&&y<H);}
signed main(){
    cin >> H >> W;
    vector<string>grid(H);
    for(auto & s : grid) cin >> s;
    vector<vector<int>>edge(400,vector<int>(400,INF));
    for(int i = 0; i < H; ++i){
        for(int j = 0; j < W; ++j){
            int idx = i * W + j;
            rep(k,4){
                int tx = j + dx[k];
                int ty = i + dy[k];
                if(valid(tx, ty) and grid[ty][tx] != '#' and grid[i][j] != '#'){
                    int tdix = 0;
                    if(tx == j) {
                        if(ty > i) tdix = idx + W;
                        else tdix = idx - W;
                    } else {
                        tdix = idx + (tx - j);
                    }
                    edge[idx][tdix] = edge[tdix][idx] = 1;
                }
            }
        }
    }
    rep(k,400)rep(i,400)rep(j,400) cmin(edge[i][j],edge[i][k] + edge[k][j]);
    int maxi = 0;
    rep(i,400)rep(j,400)if(edge[i][j] != INF) cmax(maxi, edge[i][j]);
    cout << maxi << endl;
    
}
