#include <bits/stdc++.h>
using namespace std;
using p_ii = pair<int, int>;
map<p_ii, char> mp;
map<pair<p_ii, p_ii>, int> dp;
vector<pair<int, int>> positions;
const vector<pair<int, int>> dir_list = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int h, w;
bool isLoad(p_ii pos) { return mp[pos] == '.'; }
void input() {
  cin >> h >> w;
  for (size_t i = 0; i < h; i++) {
    for (size_t j = 0; j < w; j++) {
      cin >> mp[{i, j}];
    }
  }
  for (size_t i = 0; i < h; i++) {
    for (size_t j = 0; j < w; j++) {
      positions.push_back({i, j});
    }
  }
  return;
}
int dfs(const p_ii src, const p_ii dst, map<p_ii, bool> trail, int number) {
  if (src == dst) {
    return number;
  }
  trail[src] = true;
  int dis = INT_MAX;
  for (auto dir : dir_list) {
    p_ii next = {src.first + dir.first, src.second + dir.second};
    if (next.first < 0 || next.first >= h || next.second < 0 ||
        next.second >= w) {
      continue;
    }
    if (isLoad(next) == false) {
      continue;
    }
    if (trail[next] == true) {
      continue;
    }
    dis = min(dis, dfs(next, dst, trail, number + 1));
  }
  return dis;
}
int main() {
  cin.tie(0);
  cout.sync_with_stdio(false);
  input();
  int ans = 0;
  for (size_t i = 0; i < (h * w); i++) {
    for (size_t j = i + 1; j < (h * w); j++) {
      const pair<int, int> src = positions[i];
      const pair<int, int> dst = positions[j];
      if (isLoad(src) == true & isLoad(dst) == true) {
        map<p_ii, bool> trail;
        int dis = dfs(src, dst, trail, 0);
        if (dis == INT_MAX) {
          continue;
        } else {
          ans = max(ans, dis);
        }
      }
    }
  }
  cout << ans << endl;
}
