#include <bits/stdc++.h>
using namespace std;
const long long INF = 1000000000000000001;
struct edge {
  int to, cost;
};
int dy[] = {0, 0, 1, -1};
int dx[] = {1, -1, 0, 0};
struct Road {
  double cost;
  int a, b;
};
struct pos {
  int x, y, cost;
};
int dp[21] = {};
char c[21][21] = {};
int main() {
  int h, w;
  cin >> h >> w;
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      cin >> c[j][i];
    }
  }
  queue<pos> que;
  int total = 0;
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      int d[21][21] = {};
      if (c[j][i] != '.') continue;
      pos pos1 = {j, i, 0};
      que.push(pos1);
      while (!que.empty()) {
        pos pos3 = que.front();
        que.pop();
        total = max(total, pos3.cost);
        if (c[pos3.x + 1][pos3.y] == '.' && d[pos3.x + 1][pos3.y] == 0) {
          pos pos4 = {pos3.x + 1, pos3.y, pos3.cost + 1};
          que.push(pos4);
          d[pos3.x + 1][pos3.y] = 1;
        }
        if (c[pos3.x][pos3.y + 1] == '.' && d[pos3.x][pos3.y + 1] == 0) {
          pos pos5 = {pos3.x, pos3.y + 1, pos3.cost + 1};
          que.push(pos5);
          d[pos3.x][pos3.y + 1] = 1;
        }
        if (c[pos3.x - 1][pos3.y] == '.' && d[pos3.x - 1][pos3.y] == 0) {
          pos pos6 = {pos3.x - 1, pos3.y, pos3.cost + 1};
          que.push(pos6);
          d[pos3.x - 1][pos3.y] = 1;
        }
        if (c[pos3.x][pos3.y - 1] == '.' && d[pos3.x][pos3.y - 1] == 0) {
          pos pos7 = {pos3.x, pos3.y - 1, pos3.cost + 1};
          que.push(pos7);
          d[pos3.x][pos3.y - 1] = 1;
        }
      }
    }
  }
  cout << total << endl;
  return 0;
}
