#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef std::vector<vector<int> > vvi;
typedef pair<int, int> pi;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<pi> vpi;
typedef vector<pll> vpll;
typedef vector<vll> vvll;
typedef vector<vi> vvi;
typedef vector<vector<double>> vvd;
typedef vector<double> vd;

#define debugone(x) cerr << #x << " " << x << "\n"; cerr.flush();
#define debugtwo(x) cerr << #x << "-------------" << "\n";for(auto &it: x) cerr << it << " ";cerr << "\n"; cerr.flush();
#define debugthree(x_, i_, j_) cerr << #x_ << "------------" << "\n";cerr << "from " << i_ << " to " << j_ << "\n";for(ll k_=i_; k_<=j_; k_++) cerr << x_[k_] << " ";cerr << "\n"; cerr.flush();
#define trace1(x)                cerr << #x << ": " << x << endl;
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;

const ll MOD = 1e9 + 7;
const int INF = 2e9;
const int MAX_LOG = 21;
const int MAX_N = 12800;

#define forn(i, n) for(int i = 0; i < n; i++)
#define forsn(i, s, n) for(int i = s; i < n; i++)
#define all(x) x.begin(), x.end()

int give_cnt(vector<vector<char>> &grid, int sx, int sy, int ex, int ey){
	// int ans = 0;
	int h = grid.size(), w = grid[0].size();
	vector<vector<bool>> visited(h, vector<bool>(w));
	// visited[sx][sy] = 1;
	queue<pair<int, pi>> Q;
	Q.push(make_pair(0, (make_pair(sx, sy))));
	while(!Q.empty()){
		pair<int, pi> curr = Q.front();
		Q.pop();
		int level = curr.first, x = curr.second.first, y = curr.second.second;
		if(!visited[x][y]){
			visited[x][y] = 1;
			if(ex == x && ey == y){
				return level;
			}
			vpi dxy = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
			for(pi temp : dxy){
				int dx = temp.first, dy = temp.second;
				int nextx = x + dx, nexty = y + dy;
				if(0 <= nextx && nextx < h && 0 <= nexty && nexty < w && grid[nextx][nexty] == '.' && !visited[nextx][nexty]){
					Q.push({level + 1, {nextx, nexty}});
				}
			}
		}
	}
	return INF;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int h, w;
	cin >> h >> w;
	vector<vector<char>> grid(h, vector<char>(w));
	forn(i, h){
		forn(j, w){
			cin >> grid[i][j];
		}
	}
	int ans = 0;
	// vector<vector<bool>> done(h, vector<bool> (w));
	forn(sx, h){
		forn(sy, w){
			if(grid[sx][sy] == '#'){
				continue;
			}
			forn(ex, h){
				forn(ey, w){
					pi a = {sx, sy}, b = {ex, ey};
					if(b > a){
						continue; 
					}
					if(grid[ex][ey] == '#'){
						continue;
					}
					ans = max(ans, give_cnt(grid, sx, sy, ex, ey));
					
				}
			}
		}
	}
	cout << ans << endl;
}		


Measured memory_bytes: 256