#include <bits/stdc++.h>
using namespace std;
int H, W;
vector<vector<char>> S;
vector<vector<int>> dp;
vector<int> dx = {1, 0, -1, 0};
vector<int> dy = {0, 1, 0, -1};
bool is_wall(pair<int, int>& p) {
  int i = p.first;
  int j = p.second;
  if (i < 0 || i >= H || j < 0 || j >= W) {
    return false;
  }
  return S.at(i).at(j) == '#';
}
int bfs(pair<int, int>& s) {
  queue<pair<int, int>> q;
  vector<vector<int>> d(H, vector<int>(W, 10000));
  q.push(s);
  d.at(s.first - 1).at(s.second - 1) = 0;
  while (q.size()) {
    pair<int, int> p = q.front();
    q.pop();
    for (int i = 0; i < (int)(4); i++) {
      int ni = p.first + dx.at(i);
      int nj = p.second + dy.at(i);
      if (0 < nj && nj <= W && 0 < ni && ni <= H &&
          S.at(ni - 1).at(nj - 1) != '#' && d.at(ni - 1).at(nj - 1) == 10000) {
        q.push(make_pair(ni, nj));
        d.at(ni - 1).at(nj - 1) = d.at(p.first - 1).at(p.second - 1) + 1;
      }
    }
  }
  int ret = 0;
  int dd;
  for (int i = 0; i < (int)(H); i++) {
    for (int j = 0; j < (int)(W); j++) {
      dd = d.at(i).at(j);
      if (ret < dd && dd < 10000) {
        ret = dd;
      }
    }
  }
  return ret;
}
pair<int, int> coord(int k) {
  int j = k % W + 1;
  int i = (k + 1 - j) / W + 1;
  return make_pair(i, j);
}
int main() {
  cin >> H >> W;
  S.resize(H, vector<char>(W));
  for (int i = 0; i < (int)(H); i++) {
    for (int j = 0; j < (int)(W); j++) {
      cin >> S.at(i).at(j);
    }
  }
  int answer = 0;
  int V = H * W;
  dp.resize(V, vector<int>(V, 10000));
  for (int i = 0; i < V; i++) {
    pair<int, int> ip = coord(i);
    if (is_wall(ip)) {
      continue;
    }
    int dist = bfs(ip);
    if (answer < dist && dist < 10000) {
      answer = dist;
    }
  }
  cout << answer << endl;
}
