#include <bits/stdc++.h>
using namespace std;
char maze[20][20];
int H, W;
queue<pair<int, int>> que;
int main() {
  int i, j, k, l, m;
  string line;
  int col;
  int ret;
  int maxlen(int, int);
  cin >> H >> W;
  for (i = 0; i < H; i++) {
    cin >> line;
    for (j = 0; j < W; j++) {
      maze[i][j] = *(line.c_str() + j);
    }
  }
  ret = 0;
  for (i = 0; i < H; i++) {
    for (j = 0; j < W; j++) {
      if (maze[i][j] == '#') continue;
      ret = max(ret, maxlen(i, j));
    }
  }
  printf("%d\n", ret - 1);
  return 0;
}
int mmap[20][20];
int maxlen(int i, int j) {
  int p, q;
  int mlen = 0;
  void mmove();
  for (p = 0; p < H; p++)
    for (q = 0; q < W; q++) mmap[p][q] = 0;
  mmap[i][j] = 1;
  pair<int, int> pa;
  pa.first = i;
  pa.second = j;
  que.push(pa);
  mmove();
  for (p = 0; p < H; p++)
    for (q = 0; q < W; q++) mlen = max(mlen, mmap[p][q]);
  return mlen;
}
void mmove() {
  int l;
  pair<int, int> pa;
  int p, q;
  while (que.empty() == false) {
    pa = que.front();
    que.pop();
    p = pa.first;
    q = pa.second;
    l = mmap[p][q] + 1;
    if (p > 0 && maze[p - 1][q] == '.') {
      if (mmap[p - 1][q] == 0 || mmap[p - 1][q] > l) {
        mmap[p - 1][q] = l;
        pa.first = p - 1;
        pa.second = q;
        que.push(pa);
      }
    }
    if (q > 0 && maze[p][q - 1] == '.') {
      if (mmap[p][q - 1] == 0 || mmap[p][q - 1] > l) {
        mmap[p][q - 1] = l;
        pa.first = p;
        pa.second = q - 1;
        que.push(pa);
      }
    }
    if (p < W - 1 && maze[p + 1][q] == '.') {
      if (mmap[p + 1][q] == 0 || mmap[p + 1][q] > l) {
        mmap[p + 1][q] = l;
        pa.first = p + 1;
        pa.second = q;
        que.push(pa);
      }
    }
    if (q < H - 1 && maze[p][q + 1] == '.') {
      if (mmap[p][q + 1] == 0 || mmap[p][q + 1] > l) {
        mmap[p][q + 1] = l;
        pa.first = p;
        pa.second = q + 1;
        que.push(pa);
      }
    }
  }
}
