#include <bits/stdc++.h>
using namespace std;
const int c_YET = -1;
const int INF = 1e9 + 1;
const long long LLINF = 1e17 + 1;
const int DX[9] = {0, 0, 1, -1, 1, 1, -1, -1, 0};
const int DY[9] = {1, -1, 0, 0, 1, -1, 1, -1, 0};
const long long MOD = 1e9 + 7;
const double PI = 3.14159265358979323846264338327950288;
int dst[100][100];
int R, C;
char maze[100][100];
int BFS(int Sx, int Sy, int Gx, int Gy);
void debug();
int main() {
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(30);
  cin >> R >> C;
  for (int i = 0; i < R; i++) {
    cin >> maze[i];
  }
  int ans = 0;
  for (int Sx = 0; Sx < C; Sx++) {
    for (int Sy = 0; Sy < R; Sy++) {
      for (int Gx = 0; Gx < C; Gx++) {
        for (int Gy = 0; Gy < R; Gy++) {
          int bfs = BFS(Sx, Sy, Gx, Gy);
          ans = max(ans, bfs);
        }
      }
    }
  }
  cout << ans;
}
int BFS(int Sx, int Sy, int Gx, int Gy) {
  queue<pair<int, int> > que;
  que.push(pair<int, int>(Sy, Sx));
  for (int i = 0; i < R; i++)
    for (int j = 0; j < C; j++) dst[i][j] = c_YET;
  dst[Sy][Sx] = 0;
  while (que.size()) {
    pair<int, int> p = que.front();
    que.pop();
    if (p.first == Gy && p.second == Gx) break;
    for (int i = 0; i < 4; i++) {
      int ny = p.first + DY[i];
      int nx = p.second + DX[i];
      if (ny >= 0 && ny < R && nx >= 0 && nx < C && maze[ny][nx] != '#' &&
          dst[ny][nx] == c_YET) {
        que.push(pair<int, int>(ny, nx));
        dst[ny][nx] = dst[p.first][p.second] + 1;
      }
    }
  }
  return dst[Gy][Gx];
}
void debug() {
  printf("\n");
  for (int i = 0; i < R; i++) {
    printf("\n");
    for (int j = 0; j < C; j++) printf("%d  ", dst[i][j]);
  }
}
