#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <utility>
#include <cmath>
#include <tuple>
#include <queue>
#include <bitset>
#include <set>
#include <map>
#include <list>

using ll = long long;
using ld = long double;
using namespace std;
const int INF = 1e9+100;
const ll INF64 = 7e18l;
const int mod = 1000000007;
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define ALL(a) (a).begin(), (a).end()
#define FIN ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);


int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};

int bfs(const vector<string> *v,int x,int y){
    int H = v.size();
    int W = v[0].size();
    vector<vector<int>> dist(H,vector<int>(W,-1));
    queue<pair<int,int>> que;

    int res = 0;
    que.push({x,y});
    dist[x][y] = 0;
    while(!que.empty()){
        int x = que.front().first, y = que.front().second;
        res = max(res,dist[x][y]);
        que.pop();
        for(int dir=0; dir<4;dir++){
            int nx = x + dx[dir], ny = y + dy[dir];
            if(nx<0 || nx >= H || ny < 0 || ny >= W) continue;
            if(v[nx][ny] == '#') continue;
            if(dist[nx][ny] == -1){
                dist[nx][ny] = dist[x][y] + 1;
                que.push({nx,ny});
            }
        }
    }
    return res;
}


int main(){
    FIN;
    int H,W;
    cin >> H >> W;
    vector<string> v(H);
    for(int i=0;i<H;i++) cin >> v[i];

    int ans = 0;
    for(int x=0;x<H;x++){
        for(int y=0;y<W;y++){
            if(v[x][y] == '#') continue;
            ans = max(ans,bfs(v,x,y));
        }
    }

    cout << ans << endl;
    return 0;
}