#include <bits/stdc++.h>
using namespace std;
int main() {
  int H, W;
  cin >> H >> W;
  vector<vector<char>> maze(H, vector<char>(W));
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> maze.at(i).at(j);
    }
  }
  int INF = 100000000;
  vector<int> dx(4);
  dx = {1, 0, -1, 0};
  vector<int> dy(4);
  dy = {0, 1, 0, -1};
  int maxmax = 0;
  for (int sx = 0; sx < H; sx++) {
    for (int sy = 0; sy < W; sy++) {
      if (maze.at(sx).at(sy) == '#') break;
      vector<vector<int>> d(H, vector<int>(W));
      for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
          d.at(i).at(j) = INF;
        }
      }
      queue<pair<int, int>> que;
      que.push(pair<int, int>(sx, sy));
      d.at(sx).at(sy) = 0;
      while (que.size()) {
        pair<int, int> p = que.front();
        que.pop();
        for (int i = 0; i < 4; i++) {
          int nx = p.first + dx.at(i);
          int ny = p.second + dy.at(i);
          if (0 <= nx && nx < H && 0 <= ny && ny < W &&
              maze.at(nx).at(ny) != '#' && d.at(nx).at(ny) == INF) {
            que.push(pair<int, int>(nx, ny));
            d.at(nx).at(ny) = d.at(p.first).at(p.second) + 1;
          }
        }
      }
      int max = 0;
      for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
          if (max < d.at(i).at(j) && d.at(i).at(j) != INF) max = d.at(i).at(j);
        }
      }
      if (maxmax < max) maxmax = max;
    }
  }
  cout << maxmax << endl;
  return 0;
}
