#include <bits/stdc++.h>
using namespace std;
long long llRead() {
  long long a;
  cin >> a;
  return a;
};
string stringRead() {
  string a;
  cin >> a;
  return a;
};
vector<long long> vlRead(long long a) {
  vector<long long> rv;
  for (long long i = (0); i < (a); i++) {
    long long input;
    cin >> input;
    rv.push_back(input);
  }
  return rv;
}
vector<string> vsRead(long long a) {
  vector<string> rv;
  for (long long i = (0); i < (a); i++) {
    string input;
    cin >> input;
    rv.push_back(input);
  }
  return rv;
}
vector<vector<long long>> vvlRead(long long a, long long b) {
  vector<vector<long long>> rv;
  for (long long i = (0); i < (a); i++) {
    rv.push_back(vector<long long>());
    for (long long j = (0); j < (b); j++) {
      long long input;
      cin >> input;
      rv.at(i).push_back(input);
    }
  }
  return rv;
}
vector<vector<char>> vvcRead(long long a, long long b) {
  vector<vector<char>> rv;
  for (long long i = (0); i < (a); i++) {
    rv.push_back(vector<char>());
    for (long long j = (0); j < (b); j++) {
      char input;
      cin >> input;
      rv.at(i).push_back(input);
    }
  }
  return rv;
}
void debug1(long long line, const char* name, vector<long long>& v) {
  cout << line << ":" << name << ":vector<LL>(" << v.size() << ") ";
  for (long long i = (0); i < ((long long)v.size()); i++) {
    cout << v.at(i) << " ";
  }
  cout << endl;
}
void debug1(long long line, const char* name, double i) {
  cout << line << ":" << name << ":double " << i << endl;
  ;
}
void debug1(long long line, const char* name, long long i) {
  cout << line << ":" << name << ":LL " << i << endl;
  ;
}
void debug1(long long line, const char* name, vector<string>& v) {
  cout << line << ":" << name << ":vector<string>(" << v.size() << ") ";
  for (long long i = (0); i < ((long long)v.size()); i++) {
    cout << v.at(i) << " ";
  }
  cout << endl;
}
void debug1(long long line, const char* name, vector<vector<long long>>& v) {
  cout << line << ":" << name << ":vector<vector<LL>>(" << v.size() << ") ";
  cout << endl;
  for (long long i = (0); i < ((long long)v.size()); i++) {
    for (long long j = (0); j < ((long long)v.at(i).size()); j++) {
      cout << v.at(i).at(j) << " ";
    }
    cout << ", ";
    cout << endl;
  }
  cout << endl;
}
void debug1(long long line, const char* name, vector<vector<char>>& v) {
  cout << line << ":" << name << ":vector<vector<char>>(" << v.size() << ") ";
  cout << endl;
  for (long long i = (0); i < ((long long)v.size()); i++) {
    for (long long j = (0); j < ((long long)v.at(i).size()); j++) {
      cout << v.at(i).at(j) << " ";
    }
    cout << ", ";
    cout << endl;
  }
  cout << endl;
}
void debug1(long long line, const char* name, char* s) {
  cout << line << ":" << name << ":char* " << s << endl;
  ;
}
void debug1(long long line, const char* name, char c) {
  cout << line << ":" << name << ":char " << c << endl;
  ;
}
void debug1(long long line, const char* name, string& s) {
  cout << line << ":" << name << ":string " << s << endl;
  ;
}
void debug1(long long line, const char* name, vector<const char*>& v) {
  cout << line << ":" << name << ":vector<const char*>(" << v.size() << ") ";
  for (long long i = (0); i < ((long long)v.size()); i++) {
    cout << v.at(i) << " ";
  }
  cout << endl;
}
void debug1(long long line, const char* name, priority_queue<long long>& p) {
  cout << line << ":" << name << ":priority_queue<LL>(" << p.size() << ") ";
  priority_queue<long long> copy = p;
  while (!copy.empty()) {
    cout << copy.top() << " ";
    copy.pop();
  }
  cout << endl;
}
void debug1(long long line, const char* name,
            vector<pair<long long, long long>>& v) {
  cout << line << ":" << name << ":vector<pair<LL,LL>>(" << v.size() << ") ";
  for (long long i = (0); i < ((long long)v.size()); i++) {
    cout << v.at(i).first << "," << v.at(i).second << " ";
  }
  cout << endl;
}
void debug1(long long line, const char* name, map<long long, long long>& m) {
  cout << line << ":" << name << ":map<LL,LL>(" << m.size() << ") ";
  for (auto p : m) {
    cout << p.first << "," << p.second << " ";
  }
  cout << endl;
}
void debug1(long long line, const char* name,
            multimap<long long, long long>& m) {
  cout << line << ":" << name << ":map<LL,LL>(" << m.size() << ") ";
  for (auto p : m) {
    cout << p.first << "," << p.second << " ";
  }
  cout << endl;
}
long long factm(long long n) {
  debug1(162, "n", n);
  long long ret = 1;
  for (long long i = (2); i < (n + 1); i++) {
    ret *= i;
    ret = ret % (1000000007);
  }
  debug1(168, "ret", ret);
  return ret;
}
long long inv(long long a) {
  long long b = (1000000007), u = 1, v = 0;
  while (b) {
    long long t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= (1000000007);
  if (u < 0) u += (1000000007);
  return u;
}
int main(int argc, const char* argv[]) {
  cout.precision(16);
  auto H = llRead();
  auto W = llRead();
  auto SS = vsRead(H);
  vector<vector<long long>> d(H * W, vector<long long>(H * W, 9999));
  for (long long y = (0); y < (H); y++) {
    for (long long x = (0); x < (W); x++) {
      int p = y * H + x;
      d.at(p).at(p) = 0;
      if (SS.at(y).at(x) == '.') {
        if (x < W - 1 && SS.at(y).at(x + 1) == '.') {
          d.at(p).at(p + 1) = 1;
          d.at(p + 1).at(p) = 1;
        }
        if (y < H - 1 && SS.at(y + 1).at(x) == '.') {
          d.at(p).at(p + H) = 1;
          d.at(p + H).at(p) = 1;
        }
      }
    }
  }
  for (long long k = (0); k < (H * W); k++) {
    for (long long i = (0); i < (H * W); i++) {
      for (long long j = (0); j < (H * W); j++) {
        if (d.at(i).at(j) > d.at(i).at(k) + d.at(k).at(j)) {
          d.at(i).at(j) = d.at(i).at(k) + d.at(k).at(j);
        }
      }
    }
  }
  long long m = 0;
  for (long long i = (0); i < (H * W); i++) {
    for (long long j = (0); j < (H * W); j++) {
      auto x = d.at(i).at(j);
      if ((x != 9999) && (x > m)) {
        m = x;
      }
    }
  }
  cout << m << endl;
  return 0;
}
