#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
int main() {
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  vector<vector<bool>> is_visit(h, vector<bool>(w));
  for (int i = 0; i < (h); ++i) {
    cin >> s[i];
  }
  int max = 0;
  queue<pair<pair<int, int>, int>> q;
  pair<int, int> p;
  pair<pair<int, int>, int> c;
  for (int i = 0; i < (h); ++i) {
    for (int j = 0; j < (w); ++j) {
      if (s[i][j] == '.') {
        for (int k = 0; k < (h); ++k) {
          for (int l = 0; l < (w); ++l) {
            is_visit[k][l] = false;
          }
        }
        p.first = i;
        p.second = j;
        c.first = p;
        c.second = 0;
        q.push(c);
        int path_leng = 0;
        while (!q.empty()) {
          pair<pair<int, int>, int> a = q.front();
          q.pop();
          if (a.first.first < h - 1) {
            if (s[a.first.first + 1][a.first.second] == '.') {
              if (is_visit[a.first.first + 1][a.first.second] == false) {
                p.first = a.first.first + 1;
                p.second = a.first.second;
                c.first = p;
                c.second = a.second + 1;
                if (a.second + 1 > max) {
                  max = a.second + 1;
                }
                q.push(c);
                is_visit[a.first.first + 1][a.first.second] = true;
              }
            }
          }
          if (a.first.first > 0) {
            if (s[a.first.first - 1][a.first.second] == '.') {
              if (is_visit[a.first.first - 1][a.first.second] == false) {
                p.first = a.first.first - 1;
                p.second = a.first.second;
                c.first = p;
                c.second = a.second + 1;
                if (a.second + 1 > max) {
                  max = a.second + 1;
                }
                q.push(c);
                is_visit[a.first.first - 1][a.first.second] = true;
              }
            }
          }
          if (a.first.second > 0) {
            if (s[a.first.first][a.first.second - 1] == '.') {
              if (is_visit[a.first.first][a.first.second - 1] == false) {
                p.first = a.first.first;
                p.second = a.first.second - 1;
                c.first = p;
                c.second = a.second + 1;
                if (a.second + 1 > max) {
                  max = a.second + 1;
                }
                q.push(c);
                is_visit[a.first.first][a.first.second - 1] = true;
              }
            }
          }
          if (a.first.second < w - 1) {
            if (s[a.first.first][a.first.second + 1] == '.') {
              if (is_visit[a.first.first][a.first.second + 1] == false) {
                p.first = a.first.first;
                p.second = a.first.second + 1;
                c.first = p;
                c.second = a.second + 1;
                if (a.second + 1 > max) {
                  max = a.second + 1;
                }
                q.push(c);
                is_visit[a.first.first][a.first.second + 1] = true;
              }
            }
          }
        }
      }
    }
  }
  cout << max << endl;
}
