#include <bits/stdc++.h>
using namespace std;
char maze[20][20];
int H, W;
bool check(int tempH, int tempW) {
  if (0 <= tempW && tempW < W && 0 <= tempH && tempH < H) {
    if (maze[tempH][tempW] == '.') return true;
  }
  return false;
}
bool visit(vector<int> visitH, vector<int> visitW, int tempH, int tempW) {
  for (int i = 0; i < ((int)visitH.size()); i++) {
    if (visitH[i] == tempH && visitW[i] == tempW) return false;
  }
  return true;
}
int max2D(int mat[20][20], int H, int W) {
  int max = 0;
  for (int i = 0; i < (H); i++) {
    for (int j = 0; j < (W); j++) {
      if (mat[i][j] > max) max = mat[i][j];
    }
  }
  return max;
}
int main() {
  cin >> H >> W;
  for (int i = 0; i < (H); i++)
    for (int j = 0; j < (W); j++) {
      cin >> maze[i][j];
    }
  vector<int> max;
  for (int i = 0; i < (H); i++)
    for (int j = 0; j < (W); j++) {
      int length[20][20] = {0};
      vector<int> visitH;
      vector<int> visitW;
      deque<int> deq;
      deq.push_back(i);
      deq.push_back(j);
      if (maze[i][j] == '#') continue;
      while ((int)deq.size() > 0) {
        int nowH = deq[0];
        int nowW = deq[1];
        deq.pop_front();
        deq.pop_front();
        int tempH = nowH - 1;
        int tempW = nowW;
        if (check(tempH, tempW) && visit(visitH, visitW, tempH, tempW)) {
          deq.push_back(tempH);
          deq.push_back(tempW);
          length[tempH][tempW] = length[nowH][nowW] + 1;
        }
        tempH = nowH + 1;
        tempW = nowW;
        if (check(tempH, tempW) && visit(visitH, visitW, tempH, tempW)) {
          deq.push_back(tempH);
          deq.push_back(tempW);
          length[tempH][tempW] = length[nowH][nowW] + 1;
        }
        tempH = nowH;
        tempW = nowW + 1;
        if (check(tempH, tempW) && visit(visitH, visitW, tempH, tempW)) {
          deq.push_back(tempH);
          deq.push_back(tempW);
          length[tempH][tempW] = length[nowH][nowW] + 1;
        }
        tempH = nowH;
        tempW = nowW - 1;
        if (check(tempH, tempW) && visit(visitH, visitW, tempH, tempW)) {
          deq.push_back(tempH);
          deq.push_back(tempW);
          length[tempH][tempW] = length[nowH][nowW] + 1;
        }
        visitH.push_back(nowH);
        visitW.push_back(nowW);
      }
      max.push_back(max2D(length, H, W));
    }
  cout << *max_element(max.begin(), max.end()) << endl;
  return 0;
}
