#include <bits/stdc++.h>
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
using namespace std;
using P = pair<int, int>;
using ll = long long;
const ll INF = 1LL << 60;
const double PI = 3.1415926535897932;
const int MOD = 1e9 + 7;
int h, w, d, goal_y, goal_x;
vector<vector<char>> G(20);
vector<int> py = {1, -1, 0, 0};
vector<int> px = {0, 0, 1, -1};
vector<int> dis;
void dfs(int i, int j, int times, vector<vector<bool>> visited) {
  if (i == goal_y && j == goal_x) {
    d = min(d, times);
  }
  visited[i][j] = true;
  for (int k = 0; k < 4; k++) {
    int X, Y;
    Y = i + py[k];
    X = j + px[k];
    if (0 <= X && X < w) {
      if (0 <= Y && Y < h) {
        if (!visited[Y][X] && G[Y][X] == '.') {
          dfs(Y, X, times + 1, visited);
        }
      }
    }
  }
}
int main() {
  cin >> h >> w;
  vector<P> sts;
  for (int i = 0; i < (h); ++i) {
    for (int j = 0; j < (w); ++j) {
      char ch;
      cin >> ch;
      G[i].push_back(ch);
      if (ch == '.') {
        if ((i == 0 || i == h - 1) && (j == 0 || j == w - 1)) {
          sts.push_back(make_pair(i, j));
        }
      }
    }
  }
  vector<vector<bool>> visited(20, vector<bool>(20));
  for (int i = 0; i < sts.size() - 1; i++) {
    for (int j = i + 1; j < sts.size(); j++) {
      goal_y = sts[j].first;
      goal_x = sts[j].second;
      d = 10000;
      dfs(sts[i].first, sts[i].second, 0, visited);
      if (d != 10000) {
        dis.push_back(d);
      }
    }
  }
  cout << *max_element(dis.begin(), dis.end()) << endl;
  return 0;
}
