#include <bits/stdc++.h>
struct square {
  int H, W;
  bool up;
  bool down;
  bool right;
  bool left;
  void init(int H_in, int W_in) {
    H = H_in;
    W = W_in;
    up = false;
    down = false;
    right = false;
    left = false;
  }
};
int walk(std::vector<std::vector<square> >& map,
         std::vector<std::vector<int> >& walk_min, int i, int j, int dist);
int main() {
  int H, W;
  std::cin >> H >> W;
  std::vector<std::vector<square> > map(H, std::vector<square>(W));
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      map[i][j].init(i, j);
    }
  }
  std::string S;
  for (int i = 0; i < H; i++) {
    std::cin >> S;
    for (int j = 0; j < W; j++) {
      bool tmp = S[j] == '.';
      if (i != 0) {
        map[i - 1][j].down = tmp;
      }
      if (i != H - 1) {
        map[i + 1][j].up = tmp;
      }
      if (j != 0) {
        map[i][j - 1].right = tmp;
      }
      if (j != W - 1) {
        map[i][j + 1].left = tmp;
      }
    }
  }
  int dist_max = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      std::vector<std::vector<int> > walk_list(H, std::vector<int>(W, 400));
      walk(map, walk_list, i, j, 0);
      for (int a = 0; a < H; a++) {
        for (int b = 0; b < W; b++) {
          if (walk_list[a][b] != 400 && dist_max < walk_list[a][b]) {
            dist_max = walk_list[a][b];
          }
        }
      }
    }
  }
  std::cout << dist_max << std::endl;
  return 0;
}
int walk(std::vector<std::vector<square> >& map,
         std::vector<std::vector<int> >& walk_list, int i, int j, int dist) {
  if (walk_list[i][j] > dist) {
    walk_list[i][j] = dist;
    if (map[i][j].up) {
      walk(map, walk_list, i - 1, j, dist + 1);
    }
    if (map[i][j].down) {
      walk(map, walk_list, i + 1, j, dist + 1);
    }
    if (map[i][j].right) {
      walk(map, walk_list, i, j + 1, dist + 1);
    }
    if (map[i][j].left) {
      walk(map, walk_list, i, j - 1, dist + 1);
    }
  }
  return 0;
}
