#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
long long modpow(long long a, long long n, long long mod);
long long modinv(long long a, long long mod);

using namespace std;
int main() {

	//E
	/*long long int n, k;
	cin >> n >> k;
	long long int a[100000];
	long long int i;
	for (i = 0; i < n; i++)cin >> a[i];
	long long int MOD = 1000000007;
	sort(a, a + n);
	long long int C = 1;
	for (i = 1; i <= k - 1; i++) {
		C = (C * (n - i)) % MOD;
		C = (C * modinv(i, MOD)) % MOD;
	}
	long long int j = n - k + 1;
	long long int sum = 0;
	for (i = 0; i <= n - k; i++) {
		sum = (sum + ((C * ((a[n - 1 - i] + MOD) % MOD)) % MOD)) % MOD;
		sum = (sum - ((C * ((a[i] + MOD)) % MOD) % MOD) + MOD) % MOD;
		j--;
		C = (C * j) % MOD;
		C = (C * modinv(n - 1 - i, MOD)) % MOD;

	}
	cout << sum << endl;
	return 0;
	*/
	//D
	int h, w;
	cin >> h >> w;
	int i, j;
	char s[20][20];
	for (i = 0; i < h; i++) {
		for (j = 0; j < w; j++) {
			cin >> s[i][j];
		}
	}
	int p[20][20];
	queue<pair<int, int>> que;
	pair<int, int> start;
	int maxl = 0;
	//スタートを任意に選び、そこから最も遠い点を探す
	for (i = 0; i < h; i++) {
		for (j = 0; j < w; j++) {
			memset(p, -1, sizeof(p));
			if (s[i][j] == '.') {
				p[i][j] = 0;
				que.push(pair<int, int>(i, j));
				while (que.size()) {
					start = que.front(); que.pop();
					if (start.first > 0) {
						if (s[start.first - 1][start.second] == '.') {
							if (p[start.first - 1][start.second] == -1) {
								que.push(pair<int, int>(start.first - 1, start.second));
								p[start.first - 1][start.second] = p[start.first][start.second] + 1;
								if (p[start.first - 1][start.second] > maxl)maxl = p[start.first - 1][start.second];
							}
						}
					}
					if (start.first < h - 1) {
						if (s[start.first + 1][start.second] == '.') {
							if (p[start.first + 1][start.second] == -1) {
								que.push(pair<int, int>(start.first + 1, start.second));
								p[start.first + 1][start.second] = p[start.first][start.second] + 1;
								if (p[start.first + 1][start.second] > maxl)maxl = p[start.first + 1][start.second];
							}
						}
					}
					if (start.second > 0) {
						if (s[start.first][start.second - 1] == '.') {
							if (p[start.first][start.second - 1] == -1) {
								que.push(pair<int, int>(start.first, start.second - 1));
								p[start.first][start.second - 1] = p[start.first][start.second] + 1;
								if (p[start.first][start.second - 1] > maxl)maxl = p[start.first][start.second - 1];
							}
						}
					}
					if (start.second < w - 1) {
						if (s[start.first][start.second + 1] == '.') {
							if (p[start.first][start.second + 1] == -1) {
								que.push(pair<int, int>(start.first, start.second + 1));
								p[start.first][start.second + 1] = p[start.first][start.second] + 1;
								if (p[start.first][start.second + 1] > maxl)maxl = p[start.first][start.second + 1];
							}
						}
					}
				}
			}

		}
	}
	cout << maxl << endl;
	return 0;
	

	//C
	/*int n, m;
	cin >> n >> m;
	int AC[100000];
	int WA[100000];
	int i, p;
	for (i = 0; i < n; i++) {
		AC[i] = 0;
		WA[i] = 0;
	}

	string s;
	for (i = 0; i < m; i++) {
		cin >> p;
		cin >> s;
		if (s == "AC") {
			AC[p - 1]++;
		}else{
			if(AC[p-1]==0)WA[p - 1]++;
		}
	}
	int pn = 0, sc = 0;
	for (i = 0; i < n; i++) {
		if (AC[i] > 0) {
			sc++;
			pn += WA[i];
		}
	}
	cout << sc << ' ' << pn << endl;
	return 0;
	*/
	//B
	/*int n, k, m;
	cin >> n >> k >> m;
	int sum = 0, a, i;
	for (i = 0; i < n - 1; i++) {
		cin >> a;
		sum += a;
	}
	for (i = 0; i <= k; i++) {
		if (sum + i >= n * m) {
			cout << i << endl;
			return 0;
		}
	}
	cout << -1 << endl;
	return 0;
*/	
	
	
	
	//A

	/*char c;
	cin >> c;
	cout << (char)(c + 1) << endl;
	return 0;*/
}
// a^n mod を計算する
long long modpow(long long a, long long n, long long mod) {
	long long res = 1;
	while (n > 0) {
		if (n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res;
}

// a^{-1} mod を計算する
long long modinv(long long a, long long mod) {
	return modpow(a, mod - 2, mod);
}


Measured memory_bytes: 3620