#include <bits/stdc++.h>
using namespace std;

#define dump(x) cout << (x) << '\n'
#define Int int64_t
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()

Int INF = 1e18;
Int mod = 1e9+7;
//Int mod = 998244353;

typedef struct {
    Int y, x;
} p_t;

int main() {
    Int h, w;
    bool f[21][21] = {};
    cin >> h >> w;
    for (Int i = 0; i < h; i++) {
        for (Int j = 0; j < w; j++) {
            char a;
            cin >> a;
            f[i][j] = (a == '.');
        }
    }



    
    Int res = -1;
    for (Int i = 0; i < h; i++) {
        for (Int j = 0; j < w; j++) {
            Int ma = -1;
            if (f[i][j]) {
                Int d[21][21] = {};
                for (Int ii = 0; ii < h; ii++) {
                    for (Int jj = 0; jj < w; jj++) {
                        d[ii][jj] = INF;
                    }
                }
                queue<p_t> q;
                q.push({i, j});
                d[i][j] = 0;
                while (not q.empty()) {
                p_t cur = q.front();
                q.pop();
                Int dx[] = {-1, 0, 1, 0};
                Int dy[] = {0, 1, 0, -1};
                    for (Int ii = 0; ii < 4; ii++) {
                        Int nx = dx[ii] + cur.x;
                        Int ny = dy[ii] + cur.y;
                        if (nx < 0 or w <= nx or ny < 0 or h <= ny) continue;
                        if (f[ny][nx] and d[ny][nx] > d[cur.y][cur.x] + 1) {
                            d[ny][nx] = d[cur.y][cur.x] + 1;
                            q.push({ny, nx});
                        }
                    }
                }
                for (Int k = 0; k < h; k++) {
                    for (Int l = 0; l < w; l++) {
                        if (d[k][l] != INF and ma < d[k][l]) {
                            ma = d[k][l];
                        }
                    }
                }
            }
            res = max(res, ma);
        }
    }
    dump(res);
    
    
    // Int ma = -1;
    // p_t indice;
    // for (Int i = 0; i < h; i++) {
    //     for (Int j = 0; j < w; j++) {
    //         if (d[i][j] != INF and ma < d[i][j]) {
    //             ma = d[i][j];
    //             indice = {i, j};
    //         }
    //     }
    // }
    // for (Int i = 0; i < h; i++) {
    //     for (Int j = 0; j < w; j++) {
    //         d[i][j] = INF;
    //     }
    // }
    // q.push(indice);
    // d[indice.y][indice.x] = 0;
    // while (not q.empty()) {
    //     p_t cur = q.front();
    //     q.pop();
    //     Int dx[] = {-1, 0, 1, 0};
    //     Int dy[] = {0, 1, 0, -1};
    //     for (Int i = 0; i < 4; i++) {
    //         Int nx = dx[i] + cur.x;
    //         Int ny = dy[i] + cur.y;
    //         if (nx < 0 or w <= nx or ny < 0 or h <= ny) continue;
    //         if (f[ny][nx] and d[ny][nx] > d[cur.y][cur.x] + 1) {
    //             d[ny][nx] = d[cur.y][cur.x] + 1;
    //             q.push({ny, nx});
    //         }
    //     }
    // }
    // ma = -1;
    // for (Int i = 0; i < h; i++) {
    //     for (Int j = 0; j < w; j++) {
    //         if (d[i][j] != INF and d[i][j] > ma) {
    //             ma = d[i][j];
    //         }
    //     }
    // }
    // dump(ma);
    return 0;
}


Measured memory_bytes: 256