#include <bits/stdc++.h>
using namespace std;
const int BUF = 25;
int row, col;
bool isWall[BUF][BUF];
void read() {
  cin >> row >> col;
  for (int i = 0; i < row; ++i) {
    for (int j = 0; j < col; ++j) {
      char ch;
      cin >> ch;
      isWall[i][j] = ch == '#';
    }
  }
}
int bfs(int initR, int initC) {
  queue<pair<int, int> > Q;
  int cost[BUF][BUF] = {};
  Q.push(pair<int, int>(initR, initC));
  memset(cost, -1, sizeof(cost));
  cost[initR][initC] = 0;
  while (!Q.empty()) {
    pair<int, int> cur = Q.front();
    Q.pop();
    static int dr[] = {-1, 0, 1, 0};
    static int dc[] = {0, 1, 0, -1};
    for (int i = 0; i < 4; ++i) {
      int nr = cur.first + dr[i];
      int nc = cur.second + dc[i];
      if (!(0 <= nr && nr < row && 0 <= nc && nc < col)) continue;
      if (isWall[nr][nc]) continue;
      if (cost[nr][nc] != -1) continue;
      cost[nr][nc] = cost[cur.first][cur.second] + 1;
      Q.push(pair<int, int>(nr, nc));
    }
  }
  int maxV = 0;
  for (int i = 0; i < row; ++i) {
    for (int j = 0; j < col; ++j) {
      maxV = max(maxV, cost[i][j]);
    }
  }
  return maxV;
}
void work() {
  int maxV = 0;
  for (int i = 0; i < row; ++i) {
    for (int j = 0; j < col; ++j) {
      if (!isWall[i][j]) {
        maxV = max(maxV, bfs(i, j));
      }
    }
  }
  cout << maxV << endl;
}
int main() {
  read();
  work();
  return 0;
}
