#include <iostream>
#include <vector>
#include <queue>
using namespace std;

typedef pair<int, int> P;

int main()
{
	int h, w;
	cin >> h >> w;
	bool maze[20][20] = { 0 };
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < w; j++)
		{
			char c;
			cin >> c;
			if (c == '#')
			{
				maze[i][j] = true;
			}
		}
	}
	int max = 0;
	size_t size = sizeof(visit);
	queue<P> que;
	for (int sy = 0; sy < h; sy++)for (int sx = 0; sx < w; sx++)
	{
		if (maze[sy][sx])
			continue;
		
		bool visit[20][20] = { 0 };

		P s = make_pair(sy, sx);

		que.push(s);

		int max_ = 0;

		while (1)
		{
			queue<P> que2;
			while (!que.empty())
			{
				P now = que.front();
				que.pop();
				int& ny = now.first;
				int& nx = now.second;

				if ((nx == 0 ? false : maze[ny][nx - 1] ? false : visit[ny][nx - 1] ? false : true))
				{
					que2.push(make_pair(ny, nx - 1));
					visit[ny][nx - 1] = true;
				}
				if ((nx == w - 1 ? false : maze[ny][nx + 1] ? false : visit[ny][nx + 1] ? false : true))
				{
					que2.push(make_pair(ny, nx + 1));
					visit[ny][nx + 1] = true;
				}
				if ((ny == 0 ? false : maze[ny - 1][nx] ? false : visit[ny - 1][nx] ? false : true))
				{
					que2.push(make_pair(ny - 1, nx));
					visit[ny - 1][nx] = true;
				}
				if ((ny == h - 1 ? false : maze[ny + 1][nx] ? false : visit[ny + 1][nx] ? false : true))
				{
					que2.push(make_pair(ny + 1, nx));
					visit[ny + 1][nx] = true;
				}
			}
			if (que2.empty())
				break;
			que = que2;
			max_++;
		}

		max = (max_ > max ? max_ : max);
	}
	
	cout << max << endl;

	return 0;
}