#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
const long long dx[4] = {1, 0, -1, 0};
const long long dy[4] = {0, 1, 0, -1};
const long long INF = 1e9;
const long long MOD = 1e9 + 7;
using P = pair<long long, long long>;
long long h, w;
vector<string> maze;
long long dist[25][25];
void bfs(long long y, long long x) {
  for (long long i = 0; i < (long long)h; i++)
    for (long long j = 0; j < (long long)w; j++) dist[i][j] = -1;
  queue<P> que;
  dist[y][x] = 0;
  que.push(P(y, x));
  while (!que.empty()) {
    long long y = que.front().first;
    long long x = que.front().second;
    que.pop();
    for (long long i = 0; i < (long long)4; i++) {
      long long ny = y + dy[i];
      long long nx = x + dx[i];
      if (ny >= 0 && ny < h && nx >= 0 && nx < w && maze[ny][nx] == '.' &&
          dist[ny][nx] == -1) {
        que.push(P(ny, nx));
        dist[ny][nx] = dist[y][x] + 1;
      }
    }
  }
}
signed main() {
  cin >> h >> w;
  maze.resize(h);
  for (long long i = 0; i < (long long)h; i++) cin >> maze[i];
  long long res = 0;
  for (long long i = 0; i < (long long)h; i++) {
    for (long long j = 0; j < (long long)w; j++) {
      bfs(i, j);
      for (long long k = 0; k < (long long)h; k++) {
        for (long long l = 0; l < (long long)w; l++) {
          chmax(res, dist[k][l]);
        }
      }
    }
  }
  cout << res << endl;
}
