#include <bits/stdc++.h>
using namespace std;
struct Q {
  long long x, y;
  long long operator*(Q b) { return (x * b.y - y * b.x); }
  void read() { cin >> x >> y; }
  Q operator-(Q b) { return {x - b.x, y - b.y}; }
  double operator%(Q b) { return sqrt(pow(x - b.x, 2) + pow(y - b.y, 2)); }
};
bool inters(Q a, Q b, Q c, Q d) {
  for (int i = 0; i < 2; i++) {
    Q zg = (b - a), zg1 = (b - c), zg2 = (b - d);
    long long v1 = zg * zg1, v2 = zg * zg2;
    if (v1 * v2 > 0) {
      return false;
    } else if (v1 == 0 && v2 == 0) {
      if (max(a.x, b.x) < min(c.x, d.x) || max(a.y, b.y) < min(c.y, d.y)) {
        return false;
      }
    }
    swap(a, c);
    swap(b, d);
  }
  return true;
}
bool inter(Q a, Q b, Q c, Q d) {
  if ((b - a) * (c - a) == 0) {
    if (((c.x <= b.x && c.x >= a.x) || (c.x <= a.x && c.x >= b.x)) &&
        ((c.y <= b.y && c.y >= a.y) || (c.y <= a.y && c.y >= b.y)))
      return true;
    else
      return false;
  } else if ((b - a) * (d - a) == 0) {
    if (((d.x <= b.x && d.x >= a.x) || (d.x <= a.x && d.x >= b.x)) &&
        ((d.y <= b.y && d.y >= a.y) || (d.y <= a.y && d.y >= b.y)))
      return true;
    else
      return false;
  } else if ((d - c) * (a - c) == 0) {
    if (((a.x <= d.x && a.x >= c.x) || (a.x <= c.x && a.x >= d.x)) &&
        ((a.y <= d.y && a.y >= c.y) || (a.y <= c.y && a.y >= d.y)))
      return true;
    else
      return false;
  } else if ((d - c) * (b - c) == 0) {
    if (((b.x <= d.x && b.x >= c.x) || (b.x <= c.x && b.x >= d.x)) &&
        ((b.y <= d.y && b.y >= c.y) || (b.y <= c.y && b.y >= d.y)))
      return true;
    else
      return false;
  } else {
    bool a1 = true, a2 = true, a3 = true, a4 = true;
    if ((a - c) * (d - c) < 0) {
      a1 = false;
    }
    if ((b - c) * (d - c) < 0) {
      a2 = false;
    }
    if ((c - a) * (b - a) < 0) {
      a3 = false;
    }
    if ((d - a) * (b - a) < 0) {
      a4 = false;
    }
    if (a1 != a2 && a3 != a4) {
      return true;
    } else {
      return false;
    }
  }
}
int maxdist;
vector<vector<bool>> vis;
vector<vector<char>> v;
void bfs(int a, int b) {
  queue<pair<pair<int, int>, int>> q;
  q.push({{a, b}, 0});
  while (!q.empty()) {
    int i = q.front().first.first, j = q.front().first.second;
    if (v[i][j + 1] == '.' && !vis[i][j + 1]) {
      vis[i][j + 1] = true;
      q.push({{i, j + 1}, q.front().second + 1});
    }
    if (v[i][j - 1] == '.' && !vis[i][j - 1]) {
      vis[i][j - 1] = true;
      q.push({{i, j - 1}, q.front().second + 1});
    }
    if (v[i + 1][j] == '.' && !vis[i + 1][j]) {
      vis[i + 1][j] = true;
      q.push({{i + 1, j}, q.front().second + 1});
    }
    if (v[i - 1][j] == '.' && !vis[i - 1][j]) {
      vis[i - 1][j] = true;
      q.push({{i - 1, j}, q.front().second + 1});
    }
    maxdist = max(maxdist, q.front().second);
    q.pop();
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int n, m;
  cin >> n >> m;
  v.assign(n + 2, vector<char>(m + 2, '#'));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> v[i + 1][j + 1];
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      vis.assign(n + 2, vector<bool>(m + 2, false));
      if (v[i + 1][j + 1] == '.') bfs(i + 1, j + 1);
    }
  }
  cout << maxdist << endl;
}
