#include <bits/stdc++.h>
using namespace std;
struct Corr {
  int y;
  int x;
  int depth;
};
const int INF = 2e9;
const int MOD = 1e9 + 7;
int h, w;
int y, x, depth;
int s_y, s_x, g_y, g_x;
int ans = 0;
vector<string> vec;
queue<Corr> q;
vector<int> y_vec = {0, 0, -1, +1};
vector<int> x_vec = {-1, +1, 0, 0};
int gcd(int, int);
int bfs();
int main() {
  cin >> h >> w;
  vec.resize(h);
  for (int(i) = 0; (i) < (h); (i)++) cin >> vec[i];
  for (s_y = 0; s_y < h; s_y++) {
    for (s_x = 0; s_x < w; s_x++) {
      for (g_y = 0; g_y < h; g_y++) {
        for (g_x = 0; g_x < w; g_x++) {
          Corr start = {s_y, s_x, 0};
          queue<Corr> empty;
          swap(q, empty);
          q.emplace(start);
          for (int(i) = 0; (i) < (h); (i)++) {
            for (int(j) = 0; (j) < (w); (j)++) {
              if (vec[i][j] == 'x') vec[i][j] = '.';
            }
          }
          int tmp = bfs();
          if (tmp > ans) ans = tmp;
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int bfs() {
  while (!q.empty()) {
    Corr now = q.front();
    q.pop();
    y = now.y, x = now.x, depth = now.depth;
    if (y == g_y && x == g_x) return depth;
    for (long long i = 0; i < 4; ++i) {
      Corr next = {y + y_vec[i], x + x_vec[i], depth + 1};
      if (0 <= next.y && next.y <= h - 1 && 0 <= next.x && next.x <= w - 1 &&
          vec[next.y][next.x] == '.') {
        vec[next.y][next.x] = 'x';
        q.push(next);
      }
    }
  }
  return 0;
}
