#include <bits/stdc++.h>
using namespace std;
struct Point {
  long long x;
  long long y;
};
struct PPoint {
  Point x;
  Point y;
};
long long gcd(long long a, long long b) {
  if (a < b) swap(a, b);
  if (b <= 0) return a;
  return gcd(b, a % b);
}
long long dx[]{0, 1, 0, -1};
long long dy[]{1, 0, -1, 0};
vector<string> grid;
long long H, W;
long long dist[20][20][20][20];
int32_t main() {
  cin.tie(NULL);
  ios_base::sync_with_stdio(false);
  cin >> H >> W;
  for (long long i = 0; i < H; i++) {
    string s;
    cin >> s;
    grid.push_back(s);
  }
  for (long long i = 0; i < H; i++) {
    for (long long j = 0; j < W; j++) {
      for (long long k = 0; k < H; k++) {
        for (long long m = 0; m < W; m++) {
          dist[i][j][k][m] = INT_MAX;
        }
      }
    }
  }
  for (long long i = 0; i < H; i++) {
    for (long long j = 0; j < W; j++) {
      dist[i][j][i][j] = 0;
    }
  }
  for (long long i1 = 0; i1 < H; i1++) {
    for (long long i2 = 0; i2 < W; i2++) {
      for (long long k = 0; k < 4; k++) {
        long long nx = i1 + dx[k];
        long long ny = i2 + dy[k];
        if (min(nx, ny) < 0 || nx >= H || ny >= W) continue;
        if (grid[nx][ny] == '#') continue;
        dist[i1][i2][nx][ny] = 1;
      }
    }
  }
  for (long long k1 = 0; k1 < H; k1++) {
    for (long long k2 = 0; k2 < W; k2++) {
      for (long long i1 = 0; i1 < H; i1++) {
        for (long long i2 = 0; i2 < W; i2++) {
          for (long long j1 = 0; j1 < H; j1++) {
            for (long long j2 = 0; j2 < W; j2++) {
              if (dist[i1][i2][j1][j2] >
                  dist[i1][i2][k1][k2] + dist[k1][k2][j1][j2]) {
                dist[i1][i2][j1][j2] =
                    dist[i1][i2][k1][k2] + dist[k1][k2][j1][j2];
              }
            }
          }
        }
      }
    }
  }
  long long ret = 0;
  for (long long i1 = 0; i1 < H; i1++) {
    for (long long i2 = 0; i2 < W; i2++) {
      for (long long j1 = 0; j1 < H; j1++) {
        for (long long j2 = 0; j2 < W; j2++) {
          if (dist[i1][i2][j1][j2] == INT_MAX) continue;
          ret = max(ret, dist[i1][i2][j1][j2]);
        }
      }
    }
  }
  cout << ret << '\n';
  return 0;
}
