#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using ll = long long;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
int bfstable[20][20];
bool visited[20][20];
int h, w;
queue<pii> q;
pii start, goal;
int x[4] = {-1, 1, 0, 0};
int y[4] = {0, 0, -1, 1};
int bfs(vector<string> s) {
  while (!q.empty()) {
    pii current = q.front();
    q.pop();
    for (int i = 0; i < (int)(4); i++) {
      pii next;
      next.first = current.first + x[i];
      next.second = current.second + y[i];
      if (next.first < h && next.first >= 0 && next.second < w &&
          next.second >= 0 && visited[next.first][next.second] == false &&
          s[next.first][next.second] == '.') {
        visited[next.first][next.second] = true;
        chmin(bfstable[next.first][next.second],
              bfstable[current.first][current.second] + 1);
        q.push(next);
      }
    }
    if (q.empty()) {
      return bfstable[current.first][current.second];
    }
  }
}
int main() {
  cin >> h >> w;
  vector<string> s(h);
  for (int i = 0; i < (int)(h); i++) cin >> s[i];
  int max = -1e9;
  for (int i = 0; i < (int)(h); i++)
    for (int j = 0; j < (int)(w); j++) {
      queue<pii> empty;
      swap(q, empty);
      start.first = i;
      start.second = j;
      q.push(start);
      if (s[start.first][start.second] == '.') {
        for (int i = 0; i < (int)(20); i++)
          for (int j = 0; j < (int)(20); j++) {
            bfstable[i][j] = 1e9;
            visited[i][j] = false;
          }
        bfstable[start.first][start.second] = 0;
        chmax(max, bfs(s));
      }
    }
  cout << max << endl;
  return 0;
}
