#include <bits/stdc++.h>
using namespace std;
long long H;
long long W;
char maze[3][3];
long long dist[9][9];
bool isChecked[9][9];
long long cost[9][9];
bool check_value(const long long value, const long long min,
                 const long long max);
bool check_value(const long long value, const long long min,
                 const long long max) {
  return (min <= value && value < max);
}
long long number();
long long number(const long long i, const long long j) { return i * W + j; }
long long distance(const long long start, const long long end);
long long distance(const long long start, const long long end) {
  long long i, j, min;
  for (long long i = 0; i < H * W; i++) {
    isChecked[start][i] = 0;
    cost[start][i] = 1000000000;
  }
  cost[start][end] = 0;
  while (true) {
    min = 1000000000;
    for (i = 0; i < H * W; i++) {
      if (!isChecked[start][i] && min > cost[start][i]) {
        min = cost[start][i];
      }
      if (min == 1000000000) {
        break;
      }
      for (j = 0; j < H * W; j++) {
        if (cost[start][j] == min) {
          for (i = 0; i < H * W; i++) {
            if (cost[start][i] > dist[i][j] + cost[start][j]) {
              cost[start][i] = dist[i][j] + cost[start][j];
            }
          }
        }
      }
    }
  }
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
int main() {
  cin >> H >> W;
  Fill(isChecked, false);
  for (long long i = 0; i < H; i++) {
    for (long long j = 0; j < H; j++) {
      cin >> maze[i][j];
    }
  }
  for (long long i = 0; i < H; i++) {
    for (long long j = 0; j < W; j++) {
      if (maze[i][j] == '.') {
        if (check_value(i - 1, 0, H)) {
          if (maze[i - 1][j] == '.') {
            dist[number(i, j)][number(i - 1, j)] = 1;
          }
        }
        if (check_value(j - 1, 0, H)) {
          if (maze[i][j - 1] == '.') {
            dist[number(i, j)][number(i, j - 1)] = 1;
          }
        }
        if (check_value(i + 1, 0, W)) {
          if (maze[i + 1][j] == '.') {
            dist[number(i, j)][number(i + 1, j)] = 1;
          }
        }
        if (check_value(j + 1, 0, W)) {
          if (maze[i][j + 1] == '.') {
            dist[number(i, j)][number(i, j + 1)] = 1;
          }
        }
      }
    }
  }
  for (long long i = 0; i < H * W; i++) {
    for (long long j = 0; j < H * W; j++) {
      cost[i][j] = distance(i, j);
    }
  }
  long long maxCount = 0;
  for (long long i = 0; i < H * W; i++) {
    for (long long j = 0; j < H * W; j++) {
      if (maxCount < cost[i][j]) {
        maxCount = cost[i][j];
      }
    }
  }
  cout << maxCount << endl;
  return 0;
}
