#include <bits/stdc++.h>
using namespace std;
const long long MOD = long long(1e9 + 7);
const long long INF = long long(1e18) + 7;
long long P_POW(long long i, long long n) {
  if (n == 0) return 1;
  n--;
  long long rep = i;
  while (n) {
    rep = rep * i;
    n--;
  }
  return rep;
}
unsigned GetDigit(unsigned num) {
  unsigned digit = 0;
  while (num != 0) {
    num /= 10;
    digit++;
  }
  return digit;
}
unsigned binarySearch(long long target, long long max, long long min) {
  while ((max - min) > 1) {
    if ((max + min) / 2 > target) {
      max = (max + min) / 2;
      min = min;
    } else {
      max = max;
      min = (max + min) / 2;
    }
  }
}
void f(int rest, string s) {
  char abc[] = "abc";
  if (rest == 0) {
    cout << s << endl;
  } else {
    for (int i = 0; i < 3; i++) {
      f(rest - 1, s + abc[i]);
    }
  }
}
long long h, w;
vector<vector<char>> v;
vector<long long> dx = {-1, 0, 1, 0};
vector<long long> dy = {0, -1, 0, 1};
long long bfs(long long ox, long long oy) {
  vector<vector<long long>> vd(h, vector<long long>(w, -1));
  queue<pair<long long, long long>> q;
  q.push({ox, oy});
  vd[oy][ox] = 0;
  long long res = 0;
  while (!q.empty()) {
    pair<long long, long long> vn = q.front();
    q.pop();
    res = max(res, vd[vn.second][vn.first]);
    for (long long i = 0; i < 4; i++) {
      long long nx = vn.first + dx[i];
      long long ny = vn.second + dy[i];
      if (nx < 0 || ny < 0 || nx >= w || ny >= h) continue;
      if (v[ny][nx] == '#') continue;
      if (vd[ny][nx] == -1) {
        vd[ny][nx] = res + 1;
        q.push({nx, ny});
      }
    }
  }
  return res;
}
int main() {
  char s;
  cin >> h >> w;
  vector<vector<char>> v2(h, vector<char>(w, '.'));
  for (long long i = 0; i < h; i++) {
    for (long long j = 0; j < w; j++) {
      cin >> s;
      v2[i][j] = s;
    }
  }
  long long m = 0;
  for (long long i = 0; i < w; i++) {
    for (long long j = 0; j < h; j++) {
      v = v2;
      m = max(m, bfs(i, j));
    }
  }
  cout << m;
}
