#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const int INF = 1001001001;
const int mod = 1000000007;
int h, w;
int maxi = -1;
int mini = INF;
char field[20][20] = {'#'};
int seen[20][20];
void seen_init() {
  for (int i = 0; i < (int)(20); i++) {
    for (int j = 0; j < (int)(20); j++) {
      seen[i][j] = INF;
    }
  }
}
void dfs(int now_x, int now_y, int goal_x, int goal_y, int cnt) {
  if (now_x < 0 || now_y < 0 || w <= now_x || h <= now_y) {
    return;
  }
  if (field[now_y][now_x] == '#') {
    return;
  }
  if (seen[now_y][now_x] <= cnt) {
    return;
  }
  if (now_x == goal_x && now_y == goal_y) {
    mini = min(mini, cnt);
    return;
  }
  seen[now_y][now_x] = cnt;
  int x[4] = {0, 1, 0, -1};
  int y[4] = {1, 0, -1, 0};
  for (int i = 0; i < (int)(4); i++) {
    dfs(now_x + x[i], now_y + y[i], goal_x, goal_y, cnt + 1);
  }
  if (mini == INF) {
    mini = 0;
  }
}
int main() {
  cin >> h >> w;
  for (int i = 0; i < (int)(h); i++) {
    for (int j = 0; j < (int)(w); j++) {
      cin >> field[i][j];
    }
  }
  for (int start_y = 0; start_y < (int)(h); start_y++) {
    for (int start_x = 0; start_x < (int)(w); start_x++) {
      for (int goal_y = 0; goal_y < (int)(h); goal_y++) {
        for (int goal_x = 0; goal_x < (int)(w); goal_x++) {
          seen_init();
          mini = INF;
          if (field[start_y][start_x] != '#' && field[goal_y][goal_x] != '#') {
            dfs(start_x, start_y, goal_x, goal_y, 0);
            maxi = max(maxi, mini);
          }
        }
      }
    }
  }
  cout << maxi << endl;
}
