#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, x, n) for (int i = x; i < (n); i++)
#define all(n) begin(n), end(n)
struct cww
{
    cww()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
    }
} star;
const long long INF = numeric_limits<long long>::max();
typedef long long ll;
typedef vector<int> vint;
typedef vector<char> vchar;
typedef vector<vector<int>> vvint;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef unsigned long long ull;
template <class T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b)
{
    if (b < a)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T>
vector<T> make_v(size_t a) { return vector<T>(a); }

template <typename T, typename... Ts>
auto make_v(size_t a, Ts... ts)
{
    return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type
fill_v(T &t, const V &v) { t = v; }

template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type
fill_v(T &t, const V &v)
{
    for (auto &e : t)
        fill_v(e, v);
}
using P = pair<int, int>;
vector<vector<int>> mindist(vector<vector<char>> S, P start)
{
    const char ok = '.', ng = '#';
    const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};

    int H = S.size(), W = S[0].size();
    vector<vector<int>> dist(H, vector<int>(W, -1));

    queue<P> q;
    q.emplace(start);
    int sx = start.second, sy = start.first;
    dist[sy][sx] = 0;
    while (!q.empty())
    {
        int x = q.front().second, y = q.front().first;

        q.pop();
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i], ny = y + dy[i];
            if (0 <= nx and nx < W and 0 <= ny and ny < H and S[ny][nx] == ok and dist[ny][nx] == -1)
            {
                dist[ny][nx] = dist[y][x] + 1;
                q.emplace(ny, nx);
            }
        }
    }
    return dist;
}
int max(vvint dist)
{
    int M = 0;
    int h = dist.size(), w = dist[0].size();
    for (size_t i = 0; i < h; i++)
    {
        for (size_t j = 0; j < w; j++)
        {
            chmax(M, dist[i][j]);
        }
    }
    return M;
}
int main()
{
    int H, W;
    cin >> H >> W;
    auto S = make_v<char>(H, W);
    for (size_t i = 0; i < H; i++)
    {
        for (size_t j = 0; j < W; j++)
        {
            cin >> S[i][j];
        }
    }
    int ans = 0;
    for (size_t i = 0; i < H; i++)
    {
        for (size_t j = 0; j < W; j++)
        {
            chmax(ans, max(mindist(S, {i, j})));
        }
    }
    cout << ans;
    return 0;
}