#include <bits/stdc++.h>
int const MAXG = 20;
int const INF = MAXG * MAXG + 1;
int H, W, grid[MAXG][MAXG];
int dist[MAXG][MAXG];
int dh[] = {0, 1, 0, -1};
int dw[] = {1, 0, -1, 0};
void bfs(int h1, int w1) {
  std::fill_n(dist[0], MAXG * MAXG, INF);
  std::queue<int> q;
  q.push(h1 * MAXG + w1);
  dist[h1][w1] = 0;
  while (!q.empty()) {
    int x = q.front(), h = x / MAXG, w = x % MAXG;
    q.pop();
    for (int i = 0; i < 4; ++i) {
      int hh = h + dh[i], ww = w + dw[i];
      if (hh < 0 || hh >= H) continue;
      if (ww < 0 || ww >= W) continue;
      if (grid[hh][ww] > 0) continue;
      if (dist[hh][ww] <= dist[h][w] + 1) continue;
      dist[hh][ww] = dist[h][w] + 1;
      q.push(hh * MAXG + ww);
    }
  }
}
int main() {
  std::cin >> H >> W;
  for (int h = 0; h < H; ++h)
    for (int w = 0; w < W; ++w) {
      char S;
      std::cin >> S;
      grid[h][w] = (S == '.' ? 0 : 1);
    }
  int mD = 0;
  for (int h = 0; h < H; ++h)
    for (int w = 0; w < W; ++w) {
      bfs(h, w);
      for (int h1 = 0; h1 < H; ++h1)
        for (int w1 = 0; w1 < W; ++w1) {
          if (dist[h1][w1] < INF) mD = std::max(mD, dist[h1][w1]);
        }
    }
  std::cout << mD << std::endl;
  return 0;
}
