#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;
template <typename T>
bool chmin(T& x, T y) {
  if (x > y) {
    x = y;
    return true;
  }
  return false;
}
template <typename T>
bool chmax(T& x, T y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
}
signed main() {
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  for (auto& x : s) cin >> x;
  vector<vector<int>> dist(h, vector<int>(w, MOD));
  int ma = 0;
  vector<int> dx{1, 0, -1, 0};
  vector<int> dy{0, 1, 0, -1};
  function<void(int, int)> f = [&](int i, int j) {
    dist.assign(h, vector<int>(w, MOD));
    dist[i][j] = 0;
    queue<pair<int, int>> que;
    que.emplace(i, j);
    while (!que.empty()) {
      int x, y;
      tie(x, y) = que.front();
      que.pop();
      for (int d = 0; d < 4; ++d) {
        int nx = x + dx[d];
        int ny = y + dy[d];
        if (!(nx < 0 || ny < 0 || nx >= h || ny >= w) && s[nx][ny] == '.' &&
            chmin(dist[nx][ny], dist[x][y] + 1))
          que.emplace(nx, ny);
      }
    }
    for (int i = 0; i < h; ++i)
      for (int j = 0; j < w; ++j)
        if (s[i][j] != '#') chmax(ma, dist[i][j]);
  };
  for (int i = 0; i < h; ++i)
    for (int j = 0; j < w; ++j) {
      if (s[i][j] != '#') {
        f(i, j);
        i = h - 1;
        break;
      }
    }
  for (int i = 0; i < h; ++i)
    for (int j = 0; j < w; ++j)
      if (dist[i][j] == ma) {
        f(i, j);
        i = h - 1;
        break;
      }
  cout << ma << endl;
  return 0;
}
