#include <bits/stdc++.h>
using namespace std;
char field[30][30];
int ans = 0;
int res = INT_MAX;
bool flags[30][30];
void dfs(int x, int y, int w, int z, int count) {
  if (x == w && y == z) {
    res = min(res, count);
    return;
  }
  bool flag = false;
  if (field[x + 1][y] == '.' && !flags[x + 1][y]) {
    flags[x + 1][y] = true;
    dfs(x + 1, y, w, z, count + 1);
    flags[x + 1][y] = false;
    flag = true;
  }
  if (field[x - 1][y] == '.' && !flags[x - 1][y]) {
    flags[x - 1][y] = true;
    dfs(x - 1, y, w, z, count + 1);
    flags[x - 1][y] = false;
    flag = true;
  }
  if (field[x][y + 1] == '.' && !flags[x][y + 1]) {
    flags[x][y + 1] = true;
    dfs(x, y + 1, w, z, count + 1);
    flags[x][y + 1] = false;
    flag = true;
  }
  if (field[x][y - 1] == '.' && !flags[x][y - 1]) {
    flags[x][y - 1] = true;
    dfs(x, y - 1, w, z, count + 1);
    flags[x][y - 1] = false;
    flag = true;
  }
}
int main() {
  int H, W;
  cin >> H >> W;
  for (int x = 0; x < (30); x++) {
    for (int y = 0; y < (30); y++) {
      field[x][y] = '#';
    }
  }
  for (int x = 0; x < (H); x++) {
    string s;
    cin >> s;
    for (int y = 0; y < (W); y++) {
      field[x + 1][y + 1] = s[y];
    }
  }
  for (int x = 0; x < (H); x++) {
    for (int y = 0; y < (W); y++) {
      if (field[x + 1][y + 1] == '.') {
        for (int w = 0; w < (H); w++) {
          for (int z = 0; z < (W); z++) {
            if (x == w && y == z) {
              continue;
            }
            if (field[w + 1][z + 1] == '#') {
              continue;
            }
            dfs(x + 1, y + 1, w + 1, z + 1, 0);
            ans = max(ans, res);
            res = INT_MAX;
          }
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}
