#include <bits/stdc++.h>
using namespace std;
queue<pair<int, int> > nextNode;
string s;
int H, W;
long long ans;
char grid[22][22];
bool visited[22][22];
long long dis[22][22];
int moves[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int main() {
  cin.sync_with_stdio(0);
  cin.tie(0);
  cin >> H >> W;
  for (int i = 1; i <= H; i++) {
    cin >> s;
    for (int j = 1; j <= W; j++) {
      grid[i][j] = s[j - 1] == '#';
    }
  }
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (grid[i][j] == '#') continue;
      for (int k = 1; k <= H; k++)
        for (int l = 1; l <= W; l++) visited[k][l] = false;
      nextNode.push({i, j});
      visited[i][j] = true;
      dis[i][j] = 0;
      while (!nextNode.empty()) {
        pair<int, int> cur = nextNode.front();
        nextNode.pop();
        for (int k = 0; k < 4; k++) {
          pair<int, int> newmove = {cur.first + moves[k][0],
                                    cur.second + moves[k][1]};
          if (newmove.first < 1 || newmove.second < 1 || newmove.first > H ||
              newmove.second > W)
            continue;
          if (visited[newmove.first][newmove.second] ||
              grid[newmove.first][newmove.second])
            continue;
          nextNode.push(newmove);
          visited[newmove.first][newmove.second] = true;
          dis[newmove.first][newmove.second] = dis[cur.first][cur.second] + 1;
          ans = max(ans, dis[cur.first][cur.second] + 1);
        }
      }
    }
  }
  cout << ans << '\n';
  return 0;
}
