#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<limits.h>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>

#define P pair<int,int>
#define x first
#define y second

using namespace std;
const int maxn = 25;
char str[maxn][maxn];
int num[maxn][maxn];
int dir[][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int n,m,ans,res;

queue<P>Q;

int main(void) {
	int BFS(int start_x,int start_y);
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; i ++) {
		for(int j = 0; j <= m; j ++) {
			scanf("%c",&str[i][j]);
		}
	}
	ans = 0,res = 0;
	for(int i = 1; i <= n; i ++) {
		for(int j = 1; j <= m; j ++ ) {
			if(str[i][j] == '#') continue;
			res = BFS(i,j);
			ans = max(ans,res);
		}
	}
	cout << ans << endl;
	return 0;
}

bool Check(int x,int y) {
	if(x < 1 || y < 1 || x > n || y > m) return false;
	if(str[x][y] == '#' || num[x][y]) return false;
	if(str[x][y] == '.') return true;
}

int BFS(int start_x,int start_y) {
	P a,b;
	int count = 0;
	memset(num,0,sizeof(num));
	while(!Q.empty()) Q.pop();
	a.x = start_x,a.y = start_y;
	Q.push(a);
	while(!Q.empty()) {
		a = Q.front();
		Q.pop();
		count = max(count,num[a.x][a.y]);
		int v = num[a.x][a.y];
		for(int i = 0; i < 4; i ++) {
			b.x = a.x + dir[i][0];
			b.y = a.y + dir[i][1];
			if(!Check(b.x,b.y)) continue;
			num[b.x][b.y] += v + 1;
			Q.push(b);
		}
	}
	return count;
}