#include <bits/stdc++.h>
using namespace std;
const unsigned long long mod = (unsigned long long)1e9 + 7;
struct warshall_floyd {
  static void solve(vector<vector<long long>>& d) {
    int n = d.size();
    for (int k = 0; k < n; k++) {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
        }
      }
    }
  }
};
int main(void) {
  long long h, w;
  cin >> h >> w;
  vector<string> grid(h);
  for (int i = 0; i < h; i++) {
    cin >> grid[i];
  }
  const long long INF = 1e15;
  vector<vector<long long>> g(h * w, vector<long long>(h * w, INF));
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      int id = i * w + j;
      if (i != 0) {
        int d = (i - 1) * w + j;
        if (grid[i][j] == '.' && grid[i - 1][j] == '.') {
          g[id][d] = 1;
          g[d][id] = 1;
        }
      }
      if (i != h - 1) {
        int d = (i + 1) * w + j;
        if (grid[i][j] == '.' && grid[i + 1][j] == '.') {
          g[id][d] = 1;
          g[d][id] = 1;
        }
      }
      if (j != 0) {
        int d = i * w + j - 1;
        if (grid[i][j] == '.' && grid[i][j - 1] == '.') {
          g[id][d] = 1;
          g[d][id] = 1;
        }
      }
      if (j != w - 1) {
        int d = i * w + j + 1;
        if (grid[i][j] == '.' && grid[i][j + 1] == '.') {
          g[id][d] = 1;
          g[d][id] = 1;
        }
      }
    }
  }
  warshall_floyd::solve(g);
  long long dist = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      for (int i2 = 0; i2 < h; i2++) {
        for (int j2 = 0; j2 < w; j2++) {
          int id = i * w + j;
          int id2 = i2 * w + j2;
          if (g[id][id2] != INF) {
            dist = max(dist, g[id][id2]);
          }
        }
      }
    }
  }
  cout << dist << endl;
  return 0;
}
