#include <bits/stdc++.h>
using namespace std;
template <class c>
struct rge {
  c b, e;
};
template <class c>
rge<c> range(c i, c j) {
  return rge<c>{i, j};
}
template <class c>
auto dud(c* x) -> decltype(cerr << *x, 0);
template <class c>
char dud(...);
struct debug {
  template <class c>
  debug& operator<<(const c&) {
    return *this;
  }
};
template <typename T>
T max(T a, T b, T c) {
  return max(a, max(b, c));
}
template <typename T>
T min(T a, T b, T c) {
  return min(a, min(b, c));
}
const int M = 1e9 + 7;
int h, w;
char maze[25][25];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> h >> w;
  map<int, pair<int, int> > mp;
  int cnt = 0;
  for (int i = 0; i < h; ++i)
    for (int j = 0; j < w; ++j) {
      mp[cnt++] = make_pair(i, j);
      cin >> maze[i][j];
    }
  int dist[500][500];
  for (int i = 0; i < 25; ++i) {
    for (int j = 0; j < 25; ++j) {
      pair<int, int> p1 = mp[i], p2 = mp[j];
      if (maze[p1.first][p1.second] == '#' || maze[p2.first][p2.second] == '#')
        dist[i][j] = 1e9 + 5;
      else if (p1.first >= h || p2.first >= h || p1.second >= w ||
               p2.second >= w)
        dist[i][j] = 1e9 + 5;
      else if (abs(p1.second - p2.second) + abs(p1.first - p2.first) == 1)
        dist[i][j] = 1;
      else
        dist[i][j] = 1e9 + 5;
    }
  }
  for (int k = 0; k < cnt; ++k) {
    for (int i = 0; i < cnt; ++i) {
      for (int j = 0; j < cnt; ++j) {
        if (dist[i][j] > dist[i][k] + dist[k][j])
          dist[i][j] = dist[i][k] + dist[k][j];
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < cnt; ++i) {
    for (int j = 0; j < cnt; ++j) {
      if (dist[i][j] != 1e9 + 5) ans = max(ans, dist[i][j]);
    }
  }
  cout << ans;
  return 0;
}
