#include <bits/stdc++.h>
using namespace std;
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  int r, c;
  cin >> r >> c;
  char g[r][c];
  for (int i = 0; i < r; i++) {
    for (int j = 0; j < c; j++) {
      cin >> g[i][j];
    }
  }
  int max_dis = INT_MIN;
  for (int i = 0; i < r; i++) {
    for (int j = 0; j < c; j++) {
      if (g[i][j] == '.') {
        vector<vector<int> > dis(r, vector<int>(c, 0));
        bool vis[r][c];
        memset(vis, false, sizeof(vis));
        queue<pair<int, int> > q;
        q.push({i, j});
        while (!q.empty()) {
          int u = q.front().first;
          int v = q.front().second;
          vis[u][v] = true;
          q.pop();
          if (u + 1 < r && v < c && u + 1 >= 0 && v >= 0 &&
              g[u + 1][v] == '.' && !vis[u + 1][v]) {
            dis[u + 1][v] = 1 + dis[u][v];
            q.push({u + 1, v});
          }
          if (u - 1 < r && v < c && u - 1 >= 0 && v >= 0 &&
              g[u - 1][v] == '.' && !vis[u - 1][v]) {
            dis[u - 1][v] = 1 + dis[u][v];
            q.push({u - 1, v});
          }
          if (u < r && v + 1 < c && u >= 0 && v + 1 >= 0 &&
              g[u][v + 1] == '.' && !vis[u][v + 1]) {
            dis[u][v + 1] = 1 + dis[u][v];
            q.push({u, v + 1});
          }
          if (u < r && v - 1 < c && u >= 0 && v - 1 >= 0 &&
              g[u][v - 1] == '.' && !vis[u][v - 1]) {
            dis[u][v - 1] = 1 + dis[u][v];
            q.push({u, v - 1});
          }
        }
        for (int k = 0; k < r; k++) {
          for (int l = 0; l < c; l++) {
            if (dis[k][l] > max_dis) max_dis = dis[k][l];
          }
        }
      }
    }
  }
  cout << max_dis << endl;
}
