#include <bits/stdc++.h>
using namespace std;
long long gcd(long long x, long long y) { return y ? gcd(y, x % y) : x; }
template <class T = long long>
T input() {
  T x;
  cin >> x;
  return x;
}
template <class T>
void output(T x) {
  cout << x << endl;
}
struct Vec2 {
  Vec2(int x, int y) {
    this->x = x;
    this->y = y;
  }
  int x;
  int y;
  Vec2 operator+(Vec2 other) {
    return Vec2(this->x + other.x, this->y + other.y);
  }
};
vector<vector<int>> course;
long saitankyori(Vec2 start) {
  for (auto iter : {Vec2(-1, 0), Vec2(1, 0), Vec2(0, -1), Vec2(0, 1)}) {
    Vec2 targetVec = start + iter;
    if (targetVec.x >= 0 && targetVec.x < course.size() && targetVec.y >= 0 &&
        targetVec.y < course[0].size()) {
      course[targetVec.x][targetVec.y] =
          min(course[start.x][start.y] + 1, course[targetVec.x][targetVec.y]);
      if (course[targetVec.x][targetVec.y] > course[start.x][start.y] &&
          course[targetVec.x][targetVec.y] > 0) {
        saitankyori(targetVec);
      }
    }
  }
  return 0;
}
int getMax(vector<vector<int>> c) {
  int ret = 0;
  for (auto iter : c) {
    for (auto iter2 : iter) {
      ret = max(ret, iter2);
    }
  }
  return ret;
}
int main() {
  int H = input();
  int W = input();
  vector<vector<int>> course_temp(H, vector<int>(W, 100));
  for (int i = 0; i < H; i++) {
    string s = input<string>();
    for (int j = 0; j < W; j++) {
      if (s.substr(j, 1) != ".") {
        course_temp[i][j] = -1;
      }
    }
  }
  int answer = 0;
  for (int xs = 0; xs < H; xs += 4) {
    for (int ys = 0; ys < W; ys += 4) {
      if (course_temp[xs][ys] == -1) continue;
      course = course_temp;
      course[xs][ys] = 0;
      saitankyori(Vec2(xs, ys));
      answer = max(answer, getMax(course));
    }
  }
  output(answer);
  return 0;
}
