#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int src, dst;
  int weight;
  Edge(int src, int dst, int weight) : src(src), dst(dst), weight(weight) {}
};
bool operator<(const Edge &e, const Edge &f) {
  return e.weight != f.weight
             ? e.weight > f.weight
             : (e.src != f.src ? e.src < f.src : e.dst < f.dst);
}
const int INF = 1e9;
bool spwf(const vector<vector<Edge>> &g, vector<vector<int>> &dist,
          vector<vector<int>> &inter) {
  int n = g.size();
  dist.assign(n, vector<int>(n, INF));
  for (int i = 0; i < n; i++) dist[i][i] = 0;
  for (int i = 0; i < n; i++) {
    for (auto f : g[i]) dist[i][f.dst] = f.weight;
  }
  inter.assign(n, vector<int>(n, -1));
  for (int k = 0; k < n; k++) {
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        if (dist[i][k] < INF && dist[k][j] < INF &&
            dist[i][j] > dist[i][k] + dist[k][j]) {
          dist[i][j] = dist[i][k] + dist[k][j];
          inter[i][j] = k;
        }
      }
    }
  }
  for (int i = 0; i < n; i++) {
    if (dist[i][i] < 0) return false;
  }
  return true;
}
int main() {
  int h, w;
  cin >> h >> w;
  vector<vector<int>> s(h + 1, vector<int>(w + 1));
  for (int i = 1; i <= h; ++i) {
    for (int j = 1; j <= w; ++j) {
      char tmp;
      cin >> tmp;
      s[i][j] = (tmp == '.' ? 1 : 0);
    }
  }
  vector<vector<Edge>> g(h * w + 1);
  for (int i = 1; i <= h; ++i) {
    for (int j = 1; j <= w; ++j) {
      int x = (i - 1) * w + j;
      if (j >= 2 && s[i][j - 1] == 1) {
        g[x].push_back(Edge(x, x - 1, 1));
        g[x].push_back(Edge(x - 1, x, 1));
      }
      if (j <= w - 1 && s[i][j + 1] == 1) {
        g[x].push_back(Edge(x, x + 1, 1));
        g[x].push_back(Edge(x + 1, x, 1));
      }
      if (i >= 2 && s[i - 1][j] == 1) {
        g[x].push_back(Edge(x, x - w, 1));
        g[x].push_back(Edge(x - w, x, 1));
      }
      if (i <= h - 1 && s[i + 1][j] == 1) {
        g[x].push_back(Edge(x, x + w, 1));
        g[x].push_back(Edge(x + w, x, 1));
      }
    }
  }
  vector<vector<int>> dist;
  vector<vector<int>> inter;
  spwf(g, dist, inter);
  int ans = 0;
  for (auto i : dist) {
    for (auto j : i) {
      if (j == INF) continue;
      ans = max(ans, j);
    }
  }
  cout << ans << endl;
}
