#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
struct io {
  io() {
    ios::sync_with_stdio(false);
    cin.tie(0);
  }
};
const long long int MOD = 1000000007;
const double EPS = 1e-9;
const int INF = INT_MAX;
const long long int LLINF = 1LL << 60;
struct Corr {
  int x;
  int y;
  int depth;
};
queue<Corr> q;
int bfs(vector<string>& v, int gy, int gx, int h, int w) {
  set<pair<int, int>> s;
  int dx[] = {1, 0, -1, 0};
  int dy[] = {0, -1, 0, 1};
  int res = INF;
  while (!q.empty()) {
    Corr now = q.front();
    q.pop();
    s.insert(make_pair(now.x, now.y));
    for (int i = 0; i < 4; i++) {
      Corr next = {now.x + dx[i], now.y + dy[i], now.depth + 1};
      if (next.x >= w || next.x < 0 || next.y >= h || next.y < 0) continue;
      if (s.find(make_pair(next.x, next.y)) != s.end()) continue;
      if (v[next.y][next.x] == '#') continue;
      if (next.y == gy && next.x == gx) {
        while (!q.empty()) q.pop();
        return next.depth;
      }
      s.insert(make_pair(next.x, next.y));
      q.push(next);
    }
  }
  return 0;
}
int main(void) {
  int h, w;
  cin >> h >> w;
  vector<string> v(h);
  for (int i = 0; i < (h); ++i) cin >> v[i];
  int ans = 0;
  vector<pair<int, int>> W;
  for (int i = 0; i < (h); ++i)
    for (int j = 0; j < (w); ++j) {
      if (v[i][j] == '.') W.push_back(make_pair(j, i));
    }
  string s = "....................";
  for (int i = 0; i < h; i++) {
    if (v[i] != s) break;
    if (i == h - 1) {
      cout << (39) << '\n';
      return 0;
    }
  }
  for (int i = 0; i < W.size(); i++) {
    for (int j = i + 1; j < W.size(); j++) {
      int sx = W[i].first;
      int sy = W[i].second;
      int gx = W[j].first;
      int gy = W[j].second;
      Corr c = {sx, sy, 0};
      q.push(c);
      int t = bfs(v, gy, gx, h, w);
      ans = max(ans, t);
    }
  }
  cout << (ans) << '\n';
}
