#include <bits/stdc++.h>
using namespace std;
class Edge {
 public:
  int cost;
  int from;
  int to;
  Edge(int n, int c) {
    to = n;
    cost = c;
  }
  Edge(int f, int t, int c) {
    from = f;
    to = t;
    cost = c;
  }
};
vector<Edge> g[400];
string s[20];
pair<int, int> bfs(int now, int n) {
  int d[400];
  fill(d, d + 400, 1e8 - 1);
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      q;
  q.push(pair<int, int>(0, now));
  d[now] = 0;
  while (!q.empty()) {
    pair<int, int> p = q.top();
    q.pop();
    if (p.first > d[p.second]) continue;
    for (int i = 0; i < g[p.second].size(); i++) {
      Edge e = g[p.second][i];
      if (d[e.to] > d[p.second] + 1) {
        d[e.to] = d[p.second] + 1;
        q.push(pair<int, int>(d[e.to], e.to));
      }
    }
  }
  pair<int, int> ret = pair<int, int>(-1, -1);
  for (int i = 0; i < 400; i++) {
    if (d[i] != 1e8 - 1) {
      ret = max(ret, pair<int, int>(d[i], i));
    }
  }
  return ret;
}
int main() {
  int h, w;
  int dx[4] = {0, 1, 0, -1};
  int dy[4] = {1, 0, -1, 0};
  cin >> h >> w;
  for (int i = 0; i < h; i++) cin >> s[i];
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      for (int k = 0; k < 4; k++) {
        int nx = i + dx[k];
        int ny = j + dy[k];
        if (nx >= 0 && nx < h && ny >= 0 && ny < w) {
          if (s[i][j] == '.' && s[nx][ny] == '.')
            g[i * 20 + j].push_back(Edge(nx * 20 + ny, 1));
        }
      }
    }
  }
  pair<int, int> z = bfs(0, h * w);
  pair<int, int> ans = bfs(z.second, h * w);
  cout << ans.first << endl;
  return 0;
}
