#include <bits/stdc++.h>
typedef struct {
  int x;
  int y;
} data_t;
typedef struct {
  int head;
  int tail;
  data_t data[10 ^ 5];
} queue_t;
queue_t queue;
void init_queue() { queue.head = queue.tail = 0; }
void enqueue(data_t data) { queue.data[queue.tail++] = data; }
data_t dequeue() { return queue.data[queue.head++]; }
int dist[100][100];
int h, w;
char s[100][100];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int bfs(data_t start, data_t end) {
  init_queue();
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      dist[i][j] = -1;
    }
  }
  dist[start.y][start.x] = 0;
  enqueue(start);
  while (queue.tail != queue.head) {
    data_t now = dequeue();
    for (int i = 0; i < 4; i++) {
      data_t move;
      move.x = now.x + dx[i];
      move.y = now.y + dy[i];
      if (move.x < 0 || move.x >= w || move.y >= h || move.y < 0) {
        continue;
      }
      if (s[move.y][move.x] == '#' || dist[move.y][move.x] != -1) {
        continue;
      }
      enqueue(move);
      dist[move.y][move.x] = dist[now.y][now.x] + 1;
    }
    if (dist[end.y][end.x] != -1) {
      return dist[end.y][end.x];
    }
  }
  return -1;
}
int main(void) {
  scanf("%d %d", &h, &w);
  int max = 0;
  for (int i = 0; i < h; i++) {
    scanf("%s", s[i]);
  }
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      for (int ii = 0; ii < h; ii++) {
        for (int jj = 0; jj < w; jj++) {
          if (s[i][j] == '#') {
            continue;
          }
          if (s[ii][jj] == '#') {
            continue;
          }
          data_t start, end;
          start.y = i;
          start.x = j;
          end.y = ii;
          end.x = jj;
          if (max < bfs(start, end)) {
            max = bfs(start, end);
          }
        }
      }
    }
  }
  printf("%d\n", max);
  return 0;
}
