#include <bits/stdc++.h>
using namespace std;
static char path = '.';
int h, w;
vector<vector<char>> board;
struct point {
  int i, j;
};
int sub_max(point start) {
  int max = 0;
  vector<vector<int>> graph;
  graph.assign(h, vector<int>(w, 0));
  queue<point> que;
  graph[start.i][start.j] = 0;
  que.push(start);
  while (que.size() != 0) {
    point p = que.front();
    que.pop();
    if (p.i + 1 < h && board[p.i + 1][p.j] == path) {
      point next;
      next.i = p.i + 1;
      next.j = p.j;
      if (graph[next.i][next.j] == 0) {
        que.push(next);
      }
      if (graph[next.i][next.j] < graph[p.i][p.j] + 1) {
        graph[next.i][next.j] = graph[p.i][p.j] + 1;
        if (max < graph[next.i][next.j]) {
          max = graph[next.i][next.j];
        }
      }
    }
    if (p.i - 1 > 0 && board[p.i - 1][p.j] == path) {
      point next;
      next.i = p.i - 1;
      next.j = p.j;
      if (graph[next.i][next.j] == 0) {
        que.push(next);
      }
      if (graph[next.i][next.j] < graph[p.i][p.j] + 1) {
        graph[next.i][next.j] = graph[p.i][p.j] + 1;
        if (max < graph[next.i][next.j]) {
          max = graph[next.i][next.j];
        }
      }
    }
    if (p.j + 1 < w && board[p.i][p.j + 1] == path) {
      point next;
      next.i = p.i;
      next.j = p.j + 1;
      if (graph[next.i][next.j] == 0) {
        que.push(next);
      }
      if (graph[next.i][next.j] < graph[p.i][p.j] + 1) {
        graph[next.i][next.j] = graph[p.i][p.j] + 1;
        if (max < graph[next.i][next.j]) {
          max = graph[next.i][next.j];
        }
      }
    }
    if (p.j - 1 < 0 && board[p.i][p.j - 1] == path) {
      point next;
      next.i = p.i;
      next.j = p.j - 1;
      if (graph[next.i][next.j] == 0) {
        que.push(next);
      }
      if (graph[next.i][next.j] < graph[p.i][p.j] + 1) {
        graph[next.i][next.j] = graph[p.i][p.j] + 1;
        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;
}
