#include <bits/stdc++.h>
using namespace std;
using ll=long long int;
using ld=long double;
using VI=vector<ll>;
using VD=vector<ld>;
using VVI=vector<VI>;
using VC=vector<char>;
using VVC=vector<VC>;
using VS=vector<string>;
using PLL =pair<ll,ll>;
using PLD=pair<ld,ld>;
using VPLL=vector<PLL>;
#define print(x) std::cout<<x<<"\n"
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define repd(i,n) for(ll i=(ll)(n)-1;i>=0;i--)
#define ALL(x) (x).begin(),(x).end()
#define ALLR(x) (x).rbegin(),(x).rend()
#define SZ(x) ((ll)(x).size())
#define MAX(x) *max_element((x).begin(),(x).end())
#define MIN(x) *min_element((x).begin(),(x).end())
#define SORTR(x) sort((x).rbegin(),(x).rend())
#define SORT(x) sort((x).begin(),(x).end())
#define SUM(x) accumulate((x).begin(),(x).end(), 0)
#define FILL(x,a) fill(x.begin(),x.end(),a)
#define EACH(i,x) for(typeof((x).begin()) i=(x).begin(); i!=(x).end(); ++i)
#define EXIST(v, x) (std::find(v.begin(), v.end(), x) != v.end())

const ll INF = 1e18;
const ld EPS   = 1e-10;
const int MOD  = int(1e9)+7;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
template <class BidirectionalIterator>
bool next_partial_permutation(BidirectionalIterator first, BidirectionalIterator middle,BidirectionalIterator last){reverse(middle, last); return next_permutation(first , last);}
ll gcd(ll x, ll y) { return (x % y)? gcd(y, x % y): y; }
ll lcm(ll x, ll y) { return x / gcd(x, y) * y; }
ll GCD(VI v){ll a = v[0]; for (ll i = 1; i<SZ(v); i++) {a = gcd(a, v[i]);} return a;}
ll LCM(VI v){ll a = v[0]; for (ll i = 1; i<SZ(v); i++) {a = lcm(a, v[i]);} return a;}
VI Bit2Vector(const ll bit, ll n) {	VI s;	rep(i,n) if (bit & (1 << i)) s.push_back(i); return s;}


// 幅優先探索を行うクラス
class GridBFS {
	using ll=long long int;
private:
	int H, W; // grid(街)の高さと幅
	int dx[4] = { -1, 0, 0, 1 }; // 注目座標から4近傍を探索するためのxの移動量
	int dy[4] = { 0, -1, 1, 0 }; // 注目座標から4近傍を探索するためのyの移動量

	struct Coordinate { // xy座標を表す
		ll y; // y座標
		ll x; // x座標
		ll depth; // 深さ(スタート座標では0)
	};
	vector<string> gridmap;//マップ
 public:
   int sy, sx; // スタート座標
   int gy, gx; // ゴール座標
public:
	GridBFS(vector<string> & grid) {
		gridmap=grid;
		H = grid.size(); // 街の高さ
		W = grid[0].size(); // 街の幅
		// スタート座標(sy,sx)とゴール座標(gy, gx)を街から探索してセットする
		for (int y = 0; y < H; y++) {
			for (int x = 0; x < W; x++) {
				if (grid[y][x] == 's') { // スタート地点
					sy = y; // スタート地点のy座標
					sx = x; // スタート地点のx座標
				}
				if (grid[y][x] == 'g') { // ゴール地点
					gy = y; // ゴール地点のy座標
					gx = x; // ゴール地点のx座標
				}
			}
		}
	};

	// 深さ優先探索開始
	ll search(ll dmax) {
		// まずスタート地点をqueueに格納する
		Coordinate start = { sy, sx, 0 }; // y座標, x座標, 深さ(スタートは深さ0)
		deque<Coordinate> que;
		que.push_front(start);
		// 探索済みの印(x)を入れておく
		gridmap[sy][sx] = 'x';
		// queueが空になるまで探索する
		while (!que.empty()) {
			// queueの一番上を取ってポップする
			Coordinate now = que.front(); que.pop_front();
			// スタックの頂点がゴール座標であるならその時点での深さを返す
			dmax=max(dmax,now.depth);
			//if (now.y == gy && now.x == gx) return now.depth;
			// 注目してる座標の4近傍(上下左右)を探索
			for (int i = 0; i < 4; i++) {
				Coordinate next = { now.y + dy[i], now.x + dx[i], now.depth + 1 }; // 深さは+1する
				// 街の高さや幅を超える範囲の探索はしない(範囲外エラーになるから)
				if (next.y < 0 || H <= next.y) continue;
				if (next.x < 0 || W <= next.x) continue;
				// 壁だったら無視
				if (gridmap[next.y][next.x] == '#') continue;
				// 既に探索済みなら無視
				if (gridmap[next.y][next.x] == 'x') continue;
				// 探索済みの印(x)を入れておく
				gridmap[next.y][next.x] = 'x';
				// スタックに次の座標と深さをプッシュしておく
				que.push_back(next);
			}
		}
		// 見つからなかったら-1でも返しておく
		return dmax;
	}
};

void Main()
{
	ll h,w, res=0;
	ll sx,sy,gx,gy;
	string S="No";
	ll result=0;
	cin>>h>>w;
	VS	grid(h);
	rep(j, h) cin >> grid[j];

	rep(j,h){
		rep(i,w){
			if(grid[j][i]=='#') continue;
			GridBFS dfs(grid);
			dfs.sx=i;
			dfs.sy=j;
			res=max(res,dfs.search(res));
		}
	}
	cout << res << "\n";
	return;
}


int main()
{
	std::cin.tie(0);
	std::ios_base::sync_with_stdio(false);
	std::cout << std::fixed << std::setprecision(15);
	Main();
}


Measured memory_bytes: 256