#include <bits/stdc++.h>
using namespace std;
struct p {
  int x;
  int y;
  int s;
};
int main() {
  int h, w;
  cin >> h >> w;
  int maze[h][w];
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      char s;
      cin >> s;
      if (s == '.') {
        maze[i][j] = 1;
      } else {
        maze[i][j] = 0;
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (maze[i][j] == 0) continue;
      int min_step[h][w];
      for (int i_ = 0; i_ < h; i_++) {
        for (int j_ = 0; j_ < w; j_++) {
          min_step[i_][j_] = 1000000;
        }
      }
      queue<p> que;
      que.push({i, j, 0});
      while (!que.empty()) {
        p out = que.front();
        que.pop();
        if (min_step[out.x][out.y] < out.s) continue;
        min_step[out.x][out.y] = out.s;
        if ((-1 < out.x - 1) & (maze[out.x - 1][out.y] == 1)) {
          que.push({out.x - 1, out.y, out.s + 1});
        }
        if ((-1 < out.y - 1) & (maze[out.x][out.y - 1] == 1)) {
          que.push({out.x, out.y - 1, out.s + 1});
        }
        if ((out.x + 1 < h) & (maze[out.x + 1][out.y] == 1)) {
          que.push({out.x + 1, out.y, out.s + 1});
        }
        if ((out.y + 1 < w) & (maze[out.x][out.y + 1] == 1)) {
          que.push({out.x, out.y + 1, out.s + 1});
        }
      }
      int max_step = 0;
      for (int i_ = 0; i_ < h; i_++) {
        for (int j_ = 0; j_ < w; j_++) {
          if (min_step[i_][j_] == 1000000) continue;
          if (max_step < min_step[i_][j_]) max_step = min_step[i_][j_];
        }
      }
      if (ans < max_step) ans = max_step;
    }
  }
  cout << ans << endl;
  return 0;
}
