#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const int MOD = 1000000007;
const int iINF = 1001001001;
const long long llINF = 1LL << 60;
int h, w;
void load(vector<vector<int>> mp, int x, int y, int m = 0) {
  if (x < 0 || w <= x || y < 0 || h <= y) return;
  if (mp[y][x] == -1) return;
  mp[y][x] = min(mp[y][x], m);
  load(mp, x + 1, y, m + 1);
  load(mp, x - 1, y, m + 1);
  load(mp, x, y + 1, m + 1);
  load(mp, x, y - 1, m + 1);
  return;
}
int getMax(vector<vector<int>> mp) {
  int ret = 0;
  for (int i = 0; i < (h); ++i)
    for (int j = 0; j < (w); ++j) ret = max(ret, mp[i][j]);
  return ret;
}
int main() {
  cin >> h >> w;
  vector<vector<int>> maze(h, vector<int>(w, 0));
  string s;
  vector<P> starts;
  for (int i = 0; i < (h); ++i) {
    cin >> s;
    for (int j = 0; j < (w); ++j) {
      if (s[j] == '.') {
        maze[i][j] = 0;
        starts.push_back(make_pair(j, i));
      } else
        maze[i][j] = -1;
    }
  }
  int sz = starts.size();
  int ans, tmpans;
  ans = 0;
  for (int i = 0; i < (sz); ++i) {
    tmpans = 0;
    vector<vector<int>> mp = maze;
    queue<P> que;
    int m = 0;
    que.push(starts[i]);
    while (!que.empty()) {
      P v = que.front();
      que.pop();
      P next = v;
      next.first--;
      if (0 <= next.first) {
        if (mp[next.second][next.first] == 0) {
          mp[next.second][next.first] = mp[v.second][v.first] + 1;
          que.push(next);
        }
      }
      next.first += 2;
      if (next.first < w) {
        if (mp[next.second][next.first] == 0) {
          mp[next.second][next.first] = mp[v.second][v.first] + 1;
          que.push(next);
        }
      }
      next.first--;
      next.second--;
      if (0 <= next.second) {
        if (mp[next.second][next.first] == 0) {
          mp[next.second][next.first] = mp[v.second][v.first] + 1;
          que.push(next);
        }
      }
      next.second += 2;
      if (next.second < h) {
        if (mp[next.second][next.first] == 0) {
          mp[next.second][next.first] = mp[v.second][v.first] + 1;
          que.push(next);
        }
      }
    }
    tmpans = getMax(mp);
    ans = max(ans, tmpans);
  }
  cout << ans << endl;
  return 0;
}
