#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll memo[20][20];
struct axis {
  int x;
  int y;
  int cnt;
  char dir;
};
bool mei[20][20];
void print_memo(int h, int w) {
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cout << memo[i][j] << " " << flush;
    }
    cout << endl;
  }
  cout << endl;
  return;
}
int main() {
  ll h, w;
  cin >> h >> w;
  cin.ignore();
  for (int k = 0; k < 20; k++) {
    for (int l = 0; l < 20; l++) {
      mei[k][l] = false;
      memo[k][l] = 999999999;
    }
  }
  stack<axis> stk;
  char tmp_c;
  string s;
  for (ll i = 0; i < h; i++) {
    cin >> s;
    for (ll j = 0; j < w; j++) {
      if (s[j] == '.') {
        mei[i][j] = true;
      }
    }
    cin.ignore();
  }
  axis ax;
  axis tmp_ax;
  int max = 0;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      ax.x = j;
      ax.y = i;
      ax.cnt = 0;
      ax.dir = 's';
      for (int k = 0; k < 20; k++) {
        for (int l = 0; l < 20; l++) {
          memo[k][l] = 999999999;
        }
      }
      memo[i][j] = 0;
      stk.push(ax);
      while (stk.empty() == false) {
        ax = stk.top();
        memo[ax.y][ax.x] = ax.cnt;
        stk.pop();
        if (ax.y != 0) {
          if (mei[ax.y - 1][ax.x] == true) {
            tmp_ax.x = ax.x;
            tmp_ax.y = ax.y - 1;
            tmp_ax.cnt = ax.cnt + 1;
            if (memo[tmp_ax.y][tmp_ax.x] > tmp_ax.cnt) {
              stk.push(tmp_ax);
            }
          }
        }
        if (ax.x <= w - 2) {
          if (mei[ax.y][ax.x + 1] == true) {
            tmp_ax.x = ax.x + 1;
            tmp_ax.y = ax.y;
            tmp_ax.cnt = ax.cnt + 1;
            if (memo[tmp_ax.y][tmp_ax.x] > tmp_ax.cnt) {
              stk.push(tmp_ax);
            }
          }
        }
        if (ax.x != 0) {
          if (mei[ax.y][ax.x - 1] == true) {
            tmp_ax.x = ax.x - 1;
            tmp_ax.y = ax.y;
            tmp_ax.cnt = ax.cnt + 1;
            if (memo[tmp_ax.y][tmp_ax.x] > tmp_ax.cnt) {
              stk.push(tmp_ax);
            }
          }
        }
        if (ax.y <= h - 2) {
          if (mei[ax.y + 1][ax.x] == true) {
            tmp_ax.x = ax.x;
            tmp_ax.y = ax.y + 1;
            tmp_ax.cnt = ax.cnt + 1;
            if (memo[tmp_ax.y][tmp_ax.x] > tmp_ax.cnt) {
              stk.push(tmp_ax);
            }
          }
        }
      }
      for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
          if (mei[i][j] == true) {
            if ((max < memo[i][j]) && (memo[i][j] < 999999999)) {
              max = memo[i][j];
            }
          }
        }
      }
    }
  }
  cout << max << endl;
  return 0;
}
