#include <bits/stdc++.h>
using namespace std;
struct node {
  int p;
  int q;
};
char ara[22][22];
int row, col;
int Dx[] = {-1, 1, 0, 0};
int Dy[] = {0, 0, 1, -1};
int bfs(int x1, int x2, int d1, int d2) {
  queue<node> qu;
  bool visited[row][col];
  for (int i = 0; i < row; i++) memset(visited[i], 0, sizeof(visited[i]));
  int level[row][col];
  for (int i = 0; i < row; i++) {
    for (int j = 0; j < col; j++) {
      level[i][j] = 100000000;
    }
  }
  node u;
  u.p = x1;
  u.q = x2;
  qu.push(u);
  visited[u.p][u.q] = 1;
  level[x1][x2] = 0;
  while (qu.empty() == 0) {
    u = qu.front();
    qu.pop();
    for (int i = 0; i < 4; i++) {
      node v;
      v.p = u.p + Dx[i];
      v.q = u.q + Dy[i];
      if (!visited[v.p][v.q] && ara[v.p][v.q] != '#' && 0 <= v.p && v.p < row &&
          0 <= v.q && v.q < col) {
        visited[v.p][v.q] = 1;
        level[v.p][v.q] = min(level[v.p][v.q], level[u.p][u.q] + 1);
        qu.push(v);
      }
    }
  }
  return level[d1][d2];
}
int main() {
  cin >> row >> col;
  for (int i = 0; i < row; i++) {
    for (int j = 0; j < col; j++) {
      cin >> ara[i][j];
    }
  }
  int mx = 0;
  for (int i = 0; i < row; i++) {
    for (int j = 0; j < col; j++) {
      for (int p = 0; p < row; p++) {
        for (int q = 0; q < col; q++) {
          int cur = bfs(i, j, p, q);
          if (cur != 100000000) mx = max(mx, cur);
        }
      }
    }
  }
  cout << mx << '\n';
}
