#include <bits/stdc++.h>
using namespace std;
int h;
int w;
char field[20][21];
int cost[20][21];
int INF = 100000;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
void solve();
int bfs(int x, int y);
int main() {
  scanf("%d", &h);
  scanf("%d", &w);
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      scanf(" %c", &field[i][j]);
      cost[i][j] = INF;
    }
  }
  solve();
  return 0;
}
void solve() {
  int max_dist = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      int distance = bfs(i, j);
      if (distance > max_dist) {
        max_dist = distance;
      }
    }
  }
  printf("%d\n", max_dist);
}
int bfs(int x, int y) {
  queue<pair<int, int> > que;
  que.push(pair<int, int>(x, y));
  int max_cost = 0;
  cost[x][y] = 0;
  while (que.size()) {
    pair<int, int> p1 = que.front();
    que.pop();
    int sx = p1.first;
    int sy = p1.second;
    for (int i = 0; i < 4; i++) {
      int nx = sx + dx[i];
      int ny = sy + dy[i];
      if (field[nx][ny] == '.' && 0 <= nx && nx < h && 0 <= ny && ny < w) {
        if (cost[nx][ny] == INF) {
          cost[nx][ny] = cost[sx][sy] + 1;
          if (cost[nx][ny] > max_cost) {
            max_cost = cost[nx][ny];
          }
          que.push(pair<int, int>(nx, ny));
        }
      }
    }
  }
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cost[i][j] = INF;
    }
  }
  return max_cost;
}
