#include <bits/stdc++.h>
using namespace std;
static char path = '.';
static int inf = 10000000;
int h, w;
vector<vector<char>> board;
vector<int> d_y = {1, -1, 0, 0};
vector<int> d_x = {0, 0, 1, -1};
struct point {
  int i, j;
};
int sub_max(point start) {
  int max = 0;
  vector<vector<int>> graph;
  graph.assign(h, vector<int>(w, inf));
  queue<point> que;
  if (board[start.i][start.j] == path) {
    graph[start.i][start.j] = 0;
    que.push(start);
  } else {
    return 0;
  }
  while (que.size() != 0) {
    point p = que.front();
    que.pop();
    if (p.i > h || p.i < 0 || p.j > w || p.j < 0 || board[p.i][p.j] != path) {
      continue;
    }
    for (int d = 0; d < (4); d++) {
      point next;
      next.i = p.i + d_y[d];
      next.j = p.j + d_x[d];
      if (next.i >= h || next.i < 0 || next.j >= w || next.j < 0) {
        continue;
      }
      if (graph[next.i][next.j] > graph[p.i][p.j] + 1) {
        graph[next.i][next.j] = graph[p.i][p.j] + 1;
        que.push(next);
        if (max < graph[next.i][next.j]) {
          max = graph[next.i][next.j];
        }
      }
    }
  }
  return max;
}
int main() {
  cin >> h >> w;
  board.assign(h, vector<char>(w, path));
  for (int i = 0; i < (h); i++) {
    for (int j = 0; j < (w); j++) {
      cin >> board[i][j];
    }
  }
  int max = 0;
  for (int i = 0; i < (h); i++) {
    for (int j = 0; j < (w); j++) {
      point p;
      p.i = i;
      p.j = j;
      int m = sub_max(p);
      if (max < m) {
        max = m;
      }
    }
  }
  cout << max << endl;
}
