#include <bits/stdc++.h>
using namespace std;
int N, M;
vector<vector<char>> map;
struct Point {
  int i, j;
};
int bfs(Point& s, Point& t) {
  queue<pair<Point, int>> que;
  vector<vector<bool>> visited(N + 2, vector<bool>(M + 2));
  que.push(make_pair(s, 0));
  visited[s.i][s.j] = true;
  while (!que.empty()) {
    auto item = que.front();
    que.pop();
    Point& p = item.first;
    for (int dir = 0; dir < 4; dir++) {
      int x = p.i + "0211"[dir] - '1';
      int y = p.j + "1120"[dir] - '1';
      if (x == t.i && y == t.j)
        return item.second + 1;
      else if (map[x][y] == '.' && !visited[x][y]) {
        visited[x][y] = true;
        que.push(make_pair(Point{x, y}, item.second + 1));
      }
    }
  }
  return INT_MAX;
}
int main() {
  cin >> N >> M;
  map = vector<vector<char>>(N + 2, vector<char>(M + 2, '#'));
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++) {
      cin >> map[i][j];
    }
  int maximum = INT_MIN;
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++)
      for (int i2 = 1; i2 <= N; i2++)
        for (int j2 = 1; j2 <= M; j2++) {
          if ((i != i2 || j != j2) && map[i][j] == '.' && map[i2][j2] == '.') {
            Point s{i, j};
            Point t{i2, j2};
            maximum = max(maximum, bfs(s, t));
          }
        }
  cout << maximum << endl;
  return 0;
}
