#include <bits/stdc++.h>
using namespace std;
double pi = acos(-1);
long long cei(long long x, long long y) {
  long long ans = x / y;
  if (x % y != 0) ans++;
  return ans;
}
long long gcd(long long x, long long y) { return y ? gcd(y, x % y) : x; }
long long lcm(long long x, long long y) { return x / gcd(x, y) * y; }
long long llpow(long long x, long long n) {
  long long i, ans = 1;
  for ((i) = (0); (i) < (n); (i)++) ans *= x;
  return ans;
}
long long fact(long long x) {
  long long i, ans = 1;
  for ((i) = (0); (i) < (x); (i)++) ans *= (x - i);
  return ans;
}
long long ncr(long long n, long long r) {
  return fact(n) / fact(r) / fact(n - r);
}
long long npr(long long n, long long r) { return fact(n) / fact(n - r); }
bool prime(long long a) {
  if (a <= 1) return false;
  long long i;
  for (i = 2; i * i <= a; i++) {
    if (a % i == 0) return false;
  }
  return true;
}
long long fib(long long x) {
  long long i, fibo[x + 10];
  fibo[0] = 1;
  fibo[1] = 1;
  fibo[2] = 1;
  for ((i) = (3); (i) < (x + 1); (i)++) fibo[i] = fibo[i - 1] + fibo[i - 2];
  return fibo[x];
}
long long dig(long long n) {
  long long d = 0, i = 0;
  while (n / 10 > 0) {
    i++;
    d++;
  }
  return d;
}
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
long long i, j;
int main() {
  long long h, w;
  char s[30][30];
  cin >> h >> w;
  for ((i) = (0); (i) < (h); (i)++) {
    for ((j) = (0); (j) < (w); (j)++) {
      cin >> s[i][j];
    }
  }
  queue<long long> quex, quey;
  long long ans = 0, x, y;
  long long u, v, k;
  bool visited[h][w];
  long long num[h][w];
  for ((i) = (0); (i) < (h); (i)++) {
    for ((j) = (0); (j) < (w); (j)++) {
      for ((x) = (0); (x) < (h); (x)++) {
        for ((y) = (0); (y) < (w); (y)++) {
          visited[x][y] = false;
          num[x][y] = 0;
        }
      }
      quex.push(i);
      quey.push(j);
      while (!quex.empty()) {
        u = quex.front();
        v = quey.front();
        quex.pop();
        quey.pop();
        for ((k) = (0); (k) < (4); (k)++) {
          x = u + dx[k];
          y = v + dy[k];
          if (x >= h || y >= w || x < 0 || y < 0) continue;
          if (visited[x][y] || s[x][y] == '#') continue;
          num[x][y] = num[u][v] + 1;
          ans = max(ans, num[x][y]);
          visited[x][y] = true;
          quex.push(x);
          quey.push(y);
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}
