#include <bits/stdc++.h>
using namespace std;
bool G[20][20];
vector<pair<int, int> > DXDY{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int main() {
  int h, w;
  cin >> h >> w;
  for (long long y = 0; y < h; y++)
    for (long long x = 0; x < w; x++) {
      char c;
      cin >> c;
      G[y][x] = c == '.';
    }
  int max_ = 0;
  const int INF = 10000000;
  {
    for (long long startY = 0; startY < h; startY++)
      for (long long startX = 0; startX < w; startX++)
        for (long long endY = 0; endY < h; endY++)
          for (long long endX = 0; endX < w; endX++) {
            if (!G[startY][startX]) continue;
            if (!G[endY][endX]) continue;
            if (startY == endY and startX == endX) continue;
            int dp[20][20];
            for (long long y = 0; y < h; y++)
              for (long long x = 0; x < w; x++) dp[y][x] = INF;
            queue<pair<int, int> > Q;
            Q.push({startX, startY});
            dp[startY][startX] = 0;
            bool finish = false;
            while (Q.size() and !finish) {
              auto xy = Q.front();
              Q.pop();
              for (auto&& dxdy : DXDY) {
                int x = xy.first + dxdy.first;
                int y = xy.second + dxdy.second;
                if (x < 0 or x > w) continue;
                if (y < 0 or y > h) continue;
                if (!G[y][x]) continue;
                if (dp[y][x] < INF) continue;
                dp[y][x] = dp[xy.second][xy.first] + 1;
                Q.push({x, y});
                if (y == endY and x == endX) {
                  max_ = max(max_, dp[y][x]);
                  finish = true;
                  break;
                }
              }
            }
          }
  }
  cout << max_ << endl;
  return 0;
}
