#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void coY() { cout << "Yes" << endl; }
void coN() { cout << "No" << endl; }
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
const ll INF = 1LL << 60;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int Row, Colum;
vector<string> field;
queue<pair<int, int>> q;
int main() {
  cin >> Row >> Colum;
  field.resize(Row);
  for (int i = (0); i < (Row); ++i) cin >> field[i];
  int ans = 0;
  for (int sy = 0; sy < Row; sy++) {
    for (int sx = 0; sx < Colum; sx++) {
      q.push(make_pair(sy, sx));
      int Count[25][25];
      for (int i = (0); i < (25); ++i)
        for (int j = (0); j < (25); ++j) Count[i][j] = 0;
      Count[sy][sx] = 0;
      bool seen[25][25];
      for (int i = (0); i < (25); ++i)
        for (int j = (0); j < (25); ++j) seen[i][j] = false;
      seen[sy][sx] = true;
      while (!q.empty()) {
        auto point = q.front();
        q.pop();
        int ry = point.first;
        int rx = point.second;
        for (int dir = 0; dir < 4; dir++) {
          int ny = ry + dy[dir];
          int nx = rx + dx[dir];
          if (ny < 0 || ny >= Row || nx < 0 || nx >= Colum) continue;
          if (field[ny][nx] == '#') continue;
          if (seen[ny][nx]) continue;
          q.push(make_pair(ny, nx));
          seen[ny][nx] = true;
          Count[ny][nx] = Count[ry][rx] + 1;
          chmax(ans, Count[ny][nx]);
        }
      }
    }
  }
  printf("%d\n", ans);
}
