#include <bits/stdc++.h>
using namespace std;
static const int MAX = 10010;
static const long long INFTY = 1e12;
static const long long NUMMAX = 1000000007;
static const long long MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
int H, W;
vector<string> field;
int result = 100;
int dfs_res = 0;
bool seen[510][510];
int dfs(int h, int w, int c) {
  seen[h][w] = true;
  for (int dir = 0; dir < 4; ++dir) {
    int nh = h + dx[dir];
    int nw = w + dy[dir];
    if (nh < 0 || nh >= H || nw < 0 || nw >= W) continue;
    if (field[nh][nw] == '#') continue;
    if (seen[nh][nw]) continue;
    if (field[nh][nw] == 'g') {
      seen[nh][nw] = true;
      return c + 1;
    }
    int tmp = dfs(nh, nw, c + 1);
    result = min(result, tmp);
  }
  return result;
}
int main() {
  int res = 0;
  cin >> H >> W;
  field.resize(H);
  for (int h = 0; h < H; ++h) cin >> field[h];
  memset(seen, 0, sizeof(seen));
  int sh, sw, gh, gw;
  for (int sh = 0; sh < H; ++sh) {
    for (int sw = 0; sw < W; ++sw) {
      if (field[sh][sw] == '.') {
        field[sh][sw] = 's';
        for (int gh = 0; gh < H; ++gh) {
          for (int gw = 0; gw < W; ++gw) {
            if (field[gh][gw] == '.') {
              field[gh][gw] = 'g';
              res = dfs(sh, sw, 0);
              if (seen[gh][gw]) {
                dfs_res = max(dfs_res, res);
              }
              memset(seen, 0, sizeof(seen));
              result = 100;
              field[gh][gw] = '.';
            }
          }
        }
        field[sh][sw] = '.';
      }
    }
  }
  cout << dfs_res << endl;
  return 0;
}
