#include<bits/stdc++.h>

int main(){
    using namespace std;
    unsigned long H, W;
    cin >> H >> W;
    vector<vector<unsigned long>> maps(H + 2, vector<unsigned long>(W + 2)), dist(H + 2, vector<unsigned long>(W + 2, numeric_limits<unsigned long>::max() / 5));
    unsigned long fi{0}, fj{0};
    for(unsigned long i{1}; i <= H; ++i){
        string s;
        cin >> s;
        transform(s.begin(), s.end(), maps[i].begin() + 1, [](auto c){return c == '.';});
    }
    [&]{for(unsigned long i{0}; i < H + 2; ++i)for(unsigned long j{0}; j < W + 2; ++j)if(maps[i][j]){
        fi = i;
        fj = j;
        return ;
    }}();
    const auto& dist_calc = [&maps, &dist](unsigned long start_i, unsigned long start_j){
        queue<pair<pair<unsigned long, unsigned long>, unsigned long>> q;
        q.emplace(pair<unsigned long, unsigned long>{start_i, start_j}, 0);
        dist[start_i][start_j] = 0;
        while(!q.empty()) {
            auto t = q.front();
            unsigned long i{t.first.first}, j{t.first.second}, d{t.second};
            q.pop();
            for(const auto& dir : vector<pair<unsigned long, unsigned long>>{{1, 0}, {0, 1}, {~0UL, 0}, {0, ~0UL}})if(maps[i + dir.first][j + dir.second] && dist[i + dir.first][j + dir.second] > 1000000)q.emplace(pair<unsigned long, unsigned long>{i + dir.first, j + dir.second}, dist[i + dir.first][j + dir.second] = d + 1);
        }
    };
    dist_calc(fi, fj);
    unsigned long max_dist{0};
    for(unsigned long i{0}; i < H + 2; ++i)for(unsigned long j{0}; j < W + 2; ++j)if(maps[i][j] && dist[i][j] > max_dist){
        max_dist = dist[i][j];
        fi = i;
        fj = j;
    }
    for(auto& i : dist)fill(i.begin(), i.end(), numeric_limits<unsigned long>::max() / 5);
    dist_calc(fi, fj);
    for(unsigned long i{0}; i < H + 2; ++i)for(unsigned long j{0}; j < W + 2; ++j)if(maps[i][j] && dist[i][j] > max_dist)max_dist = dist[i][j];
    cout << max_dist << endl;
    return 0;
}