#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 1e5 + 5;
const int M = 1e6;
const long long INF = (long long)(1e18);
const int inf = 1e9;
const long long MOD = 1000000007LL;
void solve() {}
int h, w;
string a[25];
int dp[25][25];
set<pair<int, int> > vis;
void reset() {
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      dp[i][j] = inf;
    }
  }
}
bool ok(int x, int y) {
  if (x < 0 || x >= h) return false;
  if (y < 0 || y >= w) return false;
  if (vis.count({x, y})) return false;
  if (a[x][y] == '#') return false;
  return true;
}
void bfs(int x1, int y1, int x2, int y2) {
  vis.clear();
  queue<pair<int, int> > q;
  q.push({x1, y1});
  vis.insert({x1, y1});
  while (!q.empty()) {
    int x = q.front().first;
    int y = q.front().second;
    q.pop();
    if (x == x1 && y == y1) dp[x][y] = 0;
    if (ok(x - 1, y)) {
      q.push({x - 1, y});
      dp[x - 1][y] = min(dp[x - 1][y], dp[x][y] + 1);
      vis.insert({x - 1, y});
    }
    if (ok(x + 1, y)) {
      q.push({x + 1, y});
      dp[x + 1][y] = min(dp[x + 1][y], dp[x][y] + 1);
      vis.insert({x + 1, y});
    }
    if (ok(x, y - 1)) {
      q.push({x, y - 1});
      dp[x][y - 1] = min(dp[x][y - 1], dp[x][y] + 1);
      vis.insert({x, y - 1});
    }
    if (ok(x, y + 1)) {
      q.push({x, y + 1});
      dp[x][y + 1] = min(dp[x][y + 1], dp[x][y] + 1);
      vis.insert({x, y + 1});
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    cin >> a[i];
  }
  int ans = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (a[i][j] == '#') continue;
      for (int k = 0; k < h; k++) {
        for (int l = 0; l < w; l++) {
          if (k == i && l == j) continue;
          if (a[k][l] == '#') continue;
          reset();
          bfs(i, j, k, l);
          ans = max(ans, dp[k][l]);
        }
      }
    }
  }
  cout << ans;
  return 0;
}
