#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const int MOD = 1e9 + 7;
const long long LINF = 1e18;
using Graph = vector<vector<int>>;
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
char S[21][21];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int main() {
  int H, W;
  cin >> H >> W;
  for (long long i = 0; i < (long long)(H); ++i) {
    for (long long j = 0; j < (long long)(W); ++j) {
      cin >> S[i][j];
    }
  }
  int count_max = 0;
  for (long long i = 0; i < (long long)(H); ++i) {
    for (long long j = 0; j < (long long)(W); ++j) {
      vector<vector<int>> v(21, vector<int>(21, -1));
      queue<pair<long long, long long>> que;
      que.push(pair<long long, long long>(i, j));
      v[i][j] = 0;
      while (true) {
        if (que.empty()) {
          break;
        }
        pair<long long, long long> p = que.front();
        que.pop();
        int y = p.first;
        int x = p.second;
        int s = v[y][x];
        for (long long k = 0; k < (long long)(4); ++k) {
          int nx = x + dx[k];
          int ny = y + dy[k];
          if (nx < 0 || nx >= W || ny < 0 || ny >= H || v[ny][nx] != -1 ||
              S[ny][nx] == '#')
            continue;
          que.push(pair<long long, long long>(ny, nx));
          v[ny][nx] = s + 1;
          count_max = max(count_max, s + 1);
        }
      }
    }
  }
  cout << count_max << endl;
  return 0;
}
