#include <bits/stdc++.h>
using namespace std;
bool is_solved[100001];
long long penalty[100001];
long long dist[20][20];
void copy_grid(string g1[], string g2[], long long h, long long w) {
  for (long long i = 0; i < h; ++i) {
    for (long long j = 0; j < w; ++j) {
      g2[i][j] = g1[i][j];
      dist[i][j] = 0;
    }
  }
}
int32_t main() {
  long long t = 1;
  while (t--) {
    long long h, w;
    cin >> h >> w;
    string grid[h];
    for (long long i = 0; i < h; ++i) {
      cin >> grid[i];
    }
    string temp[h];
    long long num = 0;
    long long max_num = 0;
    for (long long i = 0; i < h; ++i) {
      for (long long j = 0; j < w; ++j) {
        if (grid[i][j] == '.') {
          copy_grid(grid, temp, h, w);
          queue<pair<long long, long long> > q;
          q.push({i, j});
          temp[i][j] = '#';
          while (!q.empty()) {
            pair<long long, long long> pt = q.front();
            q.pop();
            long long x = pt.first, y = pt.second;
            if (x - 1 >= 0 && temp[x - 1][y] == '.') {
              dist[x - 1][y] = dist[x][y] + 1;
              temp[x - 1][y] = '#';
              max_num = max(max_num, dist[x][y] + 1);
              q.push({x - 1, y});
            }
            if (x + 1 < h && temp[x + 1][y] == '.') {
              dist[x + 1][y] = dist[x][y] + 1;
              temp[x + 1][y] = '#';
              max_num = max(max_num, dist[x][y] + 1);
              q.push({x + 1, y});
            }
            if (y - 1 >= 0 && temp[x][y - 1] == '.') {
              dist[x][y - 1] = dist[x][y] + 1;
              temp[x][y - 1] = '#';
              max_num = max(max_num, dist[x][y] + 1);
              q.push({x, y - 1});
            }
            if (y + 1 < w && temp[x][y + 1] == '.') {
              dist[x][y + 1] = dist[x][y] + 1;
              temp[x][y + 1] = '#';
              max_num = max(max_num, dist[x][y] + 1);
              q.push({x, y + 1});
            }
          }
        }
      }
    }
    cout << max_num << '\n';
  }
  return 0;
}
