#include <bits/stdc++.h>
using namespace std;
const int dinf = 1000;
const int nmax = 30;
const int kmax = 410;
int DP[kmax][kmax];
char S[nmax][nmax];
int H, W, K;
char v(int i, int j) {
  if (i < 1 || H < i || j < 1 || W < j) {
    cout << "Error Line:" << 11 << endl;
    exit(-1);
  }
  return S[i - 1][j - 1];
}
void print_v() {
  cout << H << endl;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      cout << v(i, j);
    }
    cout << endl;
  }
}
int index(int i, int j) {
  if (i < 1 || H < i || j < 1 || W < j) {
    cout << "Error Line:" << 27 << endl;
    cout << i << "," << j << endl;
    exit(-1);
  }
  return (i - 1) * W + j - 1;
}
void print_DP(void) {
  for (int i = 0; i < K; i++) {
    for (int j = 0; j < K; j++) {
      if (j != 0) {
        cout << ",";
      }
      cout << DP[i][j];
    }
    cout << endl;
  }
}
void init_DP(void) {
  for (int k1 = 0; k1 < K; k1++) {
    for (int k2 = 0; k2 < K; k2++) {
      DP[k1][k2] = dinf;
    }
  }
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      int k, l;
      int cost;
      k = index(i, j);
      DP[k][k] = 0;
      if (i != 1) {
        l = index(i - 1, j);
        if (v(i, j) != '#' && v(i - 1, j) != '#') {
          cost = 1;
        } else {
          cost = dinf;
        }
        DP[k][l] = cost;
      }
      if (i != H) {
        l = index(i + 1, j);
        if (v(i, j) != '#' && v(i + 1, j) != '#') {
          cost = 1;
        } else {
          cost = dinf;
        }
        DP[k][l] = cost;
      }
      if (j != 1) {
        l = index(i, j - 1);
        if (v(i, j) != '#' && v(i, j - 1) != '#') {
          cost = 1;
        } else {
          cost = dinf;
        }
        DP[k][l] = cost;
      }
      if (j != W) {
        l = index(1, j + 1);
        if (v(i, j) != '#' && v(i, j + 1) != '#') {
          cost = 1;
        } else {
          cost = dinf;
        }
        DP[k][l] = cost;
      }
    }
  }
}
void print_maxd() {
  int max = 0;
  for (int i = 0; i < K; i++) {
    for (int j = 0; j < K; j++) {
      if (DP[i][j] != dinf && max < DP[i][j]) {
        max = DP[i][j];
      }
    }
  }
  cout << max << endl;
}
void do_DP() {
  for (int k = 0; k < K; k++) {
    for (int i = 0; i < K; i++) {
      for (int j = 0; j < K; j++) {
        DP[i][j] = min(DP[i][j], DP[i][k] + DP[k][j]);
      }
    }
  }
}
int main() {
  int i, j;
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> H >> W;
  K = H * W;
  i = 0;
  for (i = 0; i < H; i++) {
    int p, q;
    char s[30];
    cin >> s;
    strcpy(S[i], s);
  }
  init_DP();
  do_DP();
  print_maxd();
}
