#include <bits/stdc++.h>
int h;
int w;
char maze[20][20];
int dis[20][20];
using namespace std;
struct Lat {
  int x;
  int y;
};
Lat sides[] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
void resetdis() {
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      dis[j][i] = INT32_MAX;
    }
  }
}
int main() {
  cin >> h;
  cin >> w;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      dis[j][i] = INT32_MAX;
    }
  }
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      char input;
      cin >> input;
      maze[j][i] = input;
    }
  }
  int dismax = 0;
  for (int sx = 0; sx < w; sx++) {
    for (int sy = 0; sy < h; sy++) {
      if (maze[sx][sy] != '.') {
        continue;
      }
      resetdis();
      dis[sx][sy] = 0;
      Lat pos = Lat();
      vector<Lat> a;
      vector<Lat> b;
      vector<Lat> *reserved = &a;
      vector<Lat> *next = &b;
      reserved->push_back(Lat());
      Lat *sp = &reserved->at(0);
      sp->x = sx;
      sp->y = sy;
      for (;;) {
        if (reserved->size() == 0) {
          break;
        }
        for (int i = 0; i < reserved->size(); i++) {
          Lat l = reserved->at(i);
          int d = dis[l.x][l.y] + 1;
          for (int n = 0; n < 4; n++) {
            Lat l1 = Lat();
            l1.x = l.x + sides[n].x;
            l1.y = l.y + sides[n].y;
            if (l1.x < 0 || w <= l1.x || l1.y < 0 || h <= l1.y) {
              continue;
            }
            if (maze[l1.x][l1.y] != '.') {
              continue;
            }
            if ((dis[l1.x][l1.y] <= d)) {
              continue;
            }
            dis[l1.x][l1.y] = d;
            dismax = max(d, dismax);
            next->push_back(l1);
          }
        }
        reserved->clear();
        swap(reserved, next);
      }
    }
  }
  cout << dismax;
  return 0;
}
