#include <bits/stdc++.h>
using namespace std;
vector<vector<char>> field;
vector<vector<int>> d;
vector<vector<bool>> used;
int n, m;
struct st {
  int x, y, px, py;
};
bool can(int i, int j) {
  return i >= 0 && j >= 0 && i < n && j < m && field[i][j] == '.' &&
         used[i][j] == false;
}
int BFS(pair<int, int> u, pair<int, int> v) {
  queue<st> s;
  s.push({u.first, u.second, -1, -1});
  while (!s.empty()) {
    auto cur = s.front();
    used[cur.x][cur.y] = true;
    s.pop();
    if (cur.px != -1) d[cur.x][cur.y] = d[cur.px][cur.py] + 1;
    if (can(cur.x - 1, cur.y)) s.push({cur.x - 1, cur.y, cur.x, cur.y});
    if (can(cur.x + 1, cur.y)) s.push({cur.x + 1, cur.y, cur.x, cur.y});
    if (can(cur.x, cur.y - 1)) s.push({cur.x, cur.y - 1, cur.x, cur.y});
    if (can(cur.x, cur.y + 1)) s.push({cur.x, cur.y + 1, cur.x, cur.y});
  }
  return d[v.first][v.second];
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int ans = 0;
  cin >> n >> m;
  field.resize(n, vector<char>(m));
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) cin >> field[i][j];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      for (int k = 0; k < n; k++)
        for (int l = 0; l < m; l++) {
          if (field[i][j] == '#' || field[k][l] == '#') continue;
          d.assign(n, vector<int>(m, 0));
          used.assign(n, vector<bool>(m, false));
          int cur = BFS({i, j}, {k, l});
          ans = max(ans, cur);
        }
  cout << ans << "\n";
  return 0;
}
