#include <bits/stdc++.h>
using namespace std;
using Graph = vector<vector<int>>;
char s[20][20];
int H, W;
bool board(int i, int j) {
  if (0 <= i < H && 0 <= j < W)
    return true;
  else
    return false;
}
int main() {
  int N = 0;
  cin >> H >> W;
  for (int i = 0; i < (int)(H); i++)
    for (int j = 0; j < (int)(W); j++) {
      cin >> s[i][j];
      if (s[i][j] == '.') N++;
    }
  Graph G(H * W);
  for (int i = 0; i < (int)(H); i++)
    for (int j = 0; j < (int)(W); j++) {
      int di, dj;
      di = i + 1;
      if (board(di, j)) {
        if (s[i][j] == '.' && s[di][j] == '.') {
          G[i * W + j].push_back((di * W + j));
          G[di * W + j].push_back(i * W + j);
        }
      }
      dj = j + 1;
      if (board(i, dj)) {
        if (s[i][j] == '.' && s[i][dj] == '.') {
          G[i * W + j].push_back(i * W + dj);
          G[i * W + dj].push_back(i * W + j);
        }
      }
    }
  int max = 0;
  for (int i = 0; i < (int)(H); i++)
    for (int j = 0; j < (int)(W); j++) {
      if (s[i][j] == '.') {
        vector<int> dist(H * W, -1);
        queue<int> que;
        dist[i * W + j] = 0;
        que.push(i * W + j);
        while (!que.empty()) {
          int v = que.front();
          que.pop();
          for (int nv : G[v]) {
            if (dist[nv] != -1) continue;
            dist[nv] = dist[v] + 1;
            que.push(nv);
          }
        }
        int a = *max_element(dist.begin(), dist.end());
        if (a > max) max = a;
      }
    }
  cout << max << endl;
  return 0;
}
