#include <bits/stdc++.h>
using namespace std;
using ll = long long;
static const ll INF = 1e9;
static const double pi = acos(-1.0);
double Cos(double D) { return cos(pi / 180 * D); }
class Node {
 public:
  int X, Y;
  vector<pair<int, int>> next;
  bool camable = false;
  int depth = 0;
  bool seen = false;
};
int BFS(vector<vector<Node>> nodes, int st_x, int st_y) {
  int max_depth = 0;
  queue<Node> bfs;
  nodes[st_y][st_x].seen = true;
  bfs.push(nodes[st_y][st_x]);
  while (!bfs.empty()) {
    max_depth = max(max_depth, bfs.front().depth);
    for (auto x : bfs.front().next) {
      if (!nodes[x.first][x.second].seen) {
        nodes[x.first][x.second].depth = bfs.front().depth + 1;
        nodes[x.first][x.second].seen = true;
        bfs.push(nodes[x.first][x.second]);
      }
    }
    bfs.pop();
  }
  return max_depth;
}
int Ans(int H, int W, vector<vector<Node>> nodes) {
  int ans = 0;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      ans = max(ans, BFS(nodes, j, i));
    }
  }
  return ans;
}
int main() {
  int H, W;
  cin >> H >> W;
  vector<vector<Node>> nodes(H + 2, vector<Node>(W + 2));
  for (int i = 0; i < H + 2; i++) {
    for (int j = 0; j < W + 2; j++) {
      nodes[i][j].X = j;
      nodes[i][j].Y = i;
    }
  }
  for (int i = 0; i < H; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < W; j++) {
      if (s[j] == '.') {
        nodes[i + 1][j + 1].camable = true;
      }
    }
  }
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (nodes[i - 1][j].camable)
        nodes[i][j].next.push_back(make_pair(i - 1, j));
      if (nodes[i + 1][j].camable)
        nodes[i][j].next.push_back(make_pair(i + 1, j));
      if (nodes[i][j - 1].camable)
        nodes[i][j].next.push_back(make_pair(i, j - 1));
      if (nodes[i][j + 1].camable)
        nodes[i][j].next.push_back(make_pair(i, j + 1));
    }
  }
  int ans = Ans(H, W, nodes);
  cout << ans << endl;
  return 0;
}
