#include <bits/stdc++.h>
#include <bitset>
#include <cassert>
#include <cstring>
#include <functional>
#include <iomanip>
#include <list>
#include <cmath>
#include <memory>
#include <queue>
#include <set>
#include <stack>
#include <vector>
// #include <boost/multiprecision/cpp_dec_float.hpp>
// #include <boost/multiprecision/cpp_int.hpp>
using namespace std;
#define REP(i, n) for (int64_t i = 0; i < (int64_t)n; i++)
#define REP_FOR(i, a, b) for (int64_t i = (int64_t)a; i < (int64_t)b; i++)
#define REP_REV(i, a, b) for (int64_t i = (int64_t)a; i > (int64_t)b; i--)
#define FORALL(v) (v).begin(), (v).end()
#define mp(a, b) make_pair(a, b)
#define eb(x) emplace_back(x)
#define F first
#define S second
typedef long long ll;
typedef long double ld;
typedef pair<int64_t, int64_t> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<int64_t> vii;
typedef vector<vii> vvii;
const ll mod = 1e9 + 7;
const int64_t infi = 1147483600;
const ll infl = 4e18 + 5;
const char EOL = '\n';
//cout << fixed << setprecision(17) << res << endl;
// const ll MOD = 1000000009;

#define M 1000000007

int calc(vector<vector<int>> s, int h, int w, int i, int j) {
    if (s[i][j] != 0) {
        return 0;
    }
    //if (s[i+1][j] == 0 && s[i-1][j] == 0) {
    //    return 0;
    //}
    //if (s[i][j+1] == 0 && s[i][j-1] == 0) {
    //    return 0;
    //}
    vector<vector<int>> m(h+2, vector<int>(w+2, -1));
    set<pair<int,int>> q;
    q.insert(make_pair(i, j));
    m[i][j] = 0;
    int res = 0;
    while (!q.empty()) {
        auto iter = q.begin();
        int u = iter->first;
        int v = iter->second;
        q.erase(iter);
        if (s[u+1][v] == 0 && (m[u+1][v] == -1 || m[u+1][v] > m[u][v] + 1)) {
            m[u+1][v] = m[u][v] + 1;
            q.insert(make_pair(u+1,v));
        }
        if (s[u][v+1] == 0 && (m[u][v+1] == -1 || m[u][v+1] > m[u][v] + 1) ) {
            m[u][v+1] = m[u][v] + 1;
            q.insert(make_pair(u,v+1));
        }
        if (s[u-1][v] == 0 && (m[u-1][v] == -1 || m[u-1][v] > m[u][v] + 1) ) {
            m[u-1][v] = m[u][v] + 1;
            q.insert(make_pair(u-1,v));
        }
        if (s[u][v-1] == 0 && (m[u][v-1] == -1 || m[u][v-1] > m[u][v] + 1) ) {
            m[u][v-1] = m[u][v] + 1;
            q.insert(make_pair(u,v-1));
        }
    }
    for (ll u = 0; u < h; ++u) {
        for (ll v = 0; v < w; ++v) {
            res = max(res, m[u+1][v+1]);
            //if (m[u+1][v+1] == -1) {
            //    cerr << "#";
            //} else {
            //    cerr << m[u+1][v+1];
            //}
        }
        //cerr << endl;
    }
    //cerr << res << endl;
    //cerr << endl;
    return res;
}

int main() {
    int h, w;
    cin >> h >> w;
    vector<vector<int>> s(h+2, vector<int>(w+2,-1));
    for (int i = 0; i < h; ++i) {
        string in;
        cin >> in;
        for (int j = 0; j < w; ++j) {
            if (in[j] == '.') {
                s[i+1][j+1] = 0;
            }
        }
    }
    int res = 0;
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            int ret = calc(s, h, w, i+1, j+1);
            if (res < ret) res = ret;
        }
    }
    cout << res << endl;
}


Measured memory_bytes: 256