#include <bits/stdc++.h>
using namespace std;
int main() {
  int H, W;
  cin >> H >> W;
  const int N = H * W;
  vector<vector<char>> maze(H + 2, vector<char>(W + 2, '#'));
  for (int y = 1; y <= H; ++y) {
    for (int x = 1; x <= W; ++x) {
      cin >> maze[y][x];
    }
  }
  constexpr int INF = 0x20000000;
  vector<vector<int>> graph(H * W, vector<int>(H * W, INF));
  auto connect = [&](int x, int y, int x2, int y2) {
    int b = (y - 1) * W + x - 1;
    if (x != x2 || y != y2) {
      int e = (y2 - 1) * W + x2 - 1;
      graph[b][e] = 1;
      graph[e][b] = 1;
    } else {
      graph[b][b] = 0;
    }
  };
  for (int y = 1; y <= H; ++y) {
    for (int x = 1; x <= W; ++x) {
      connect(x, y, x, y);
      if (maze[y][x] == '.') {
        if (maze[y][x - 1] == '.') connect(x, y, x - 1, y);
        if (maze[y][x + 1] == '.') connect(x, y, x + 1, y);
        if (maze[y - 1][x] == '.') connect(x, y, x, y - 1);
        if (maze[y + 1][x] == '.') connect(x, y, x, y + 1);
      }
    }
  }
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      for (int k = 0; k < N; ++k) {
        graph[i][j] = graph[j][i] = min(graph[i][j], graph[i][k] + graph[k][j]);
      }
    }
  }
  int maxpath = 0;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      int p = graph[i][j];
      if (p != INF) maxpath = max(p, maxpath);
    }
  }
  cout << maxpath << '\n';
}
