#include <bits/stdc++.h>
using namespace std;
constexpr int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};
constexpr long long inf = 100000000000000;
vector<vector<int>> dist;
vector<vector<char>> maze;
int h, w;
bool check(int mid) { return false; }
long long serch(long long ok, long long ng) {
  while (abs(ok - ng) > 1) {
    long long mid = (ok + ng) / 2;
    if (check(mid))
      ok = mid;
    else
      ng = mid;
  }
  return ok;
}
int bfs(int x, int y) {
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      dist[i][j] = 0;
    }
  }
  queue<pair<int, int>> q;
  q.push(make_pair(x, y));
  while (!q.empty()) {
    pair<int, int> nq = q.front();
    q.pop();
    for (int i = 0; i < 4; i++) {
      int nx = nq.first + di[i];
      int ny = nq.second + dj[i];
      if (0 <= nx && nx < h && 0 <= ny && ny < w && maze[nx][ny] == '.' &&
          dist[nx][ny] < dist[nq.first][nq.second] + 1) {
        q.push(make_pair(nx, ny));
        dist[nx][ny] = dist[nq.first][nq.second] + 1;
      }
    }
  }
  int m = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      m = max(m, dist[i][j]);
    }
  }
  return m;
}
int main() {
  cin >> h >> w;
  dist.resize(h);
  maze.resize(h);
  for (int i = 0; i < h; i++) {
    dist[i].resize(w);
    maze[i].resize(w);
    for (int j = 0; j < w; j++) {
      cin >> maze[i][j];
    }
  }
  int ans = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (maze[i][j] == '.') {
        ans = max(ans, bfs(i, j));
      }
    }
  }
  cout << ans << endl;
}
