#include <bits/stdc++.h>
using namespace std;
struct cww {
  cww() {
    ios::sync_with_stdio(false);
    cin.tie(0);
  }
} star;
const int INF = numeric_limits<int>::max();
int main() {
  int row{}, col{};
  int sy{}, sx{};
  int gy{}, gx{};
  cin >> row >> col;
  char C[row + 1][col + 1];
  char CC[row + 1][col + 1];
  for (int i = 0; i < (row); i++) {
    for (int j = 0; j < (col); j++) {
      cin >> CC[i + 1][j + 1];
    }
  }
  for (int i = 0; i < (row); i++) {
    for (int j = 0; j < (col); j++) {
      C[i + 1][j + 1] = CC[i + 1][j + 1];
    }
  }
  int ans = 0;
  for (int ii = 1; ii <= row; ii++) {
    for (int jj = 1; jj <= col; jj++) {
      for (int kk = 1; kk <= row; kk++) {
        for (int ll = 1; ll <= col; ll++) {
          C[ii][jj] = '.';
          C[kk][ll] = '.';
          int distance[row + 1][col + 1];
          for (int i = 0; i < (row + 1); i++)
            for (int j = 0; j < (col + 1); j++) distance[i][j] = INF;
          queue<pair<int, int> > q;
          q.emplace(ii, jj);
          distance[ii][jj] = 0;
          int dy[4] = {1, 0, -1, 0}, dx[4] = {0, 1, 0, -1};
          while (!q.empty()) {
            pair<int, int> now = q.front();
            q.pop();
            for (int i = 0; i < (4); i++) {
              int ny = now.first + dy[i], nx = now.second + dx[i];
              if (1 <= ny && ny <= row && 1 <= nx && nx <= col &&
                  C[ny][nx] != '#' && distance[ny][nx] == INF) {
                q.emplace(ny, nx);
                distance[ny][nx] = distance[now.first][now.second] + 1;
              }
            }
          }
          if (C[kk][ll] == '.') ans = max(ans, distance[kk][ll]);
          C[ii][jj] = CC[ii][jj];
          C[kk][ll] = CC[kk][ll];
        }
      }
    }
  }
  std::cout << ans << std::endl;
}
