#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>;
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 < ((ll)(v).size()); i++) {
    a = gcd(a, v[i]);
  }
  return a;
}
ll LCM(VI v) {
  ll a = v[0];
  for (ll i = 1; i < ((ll)(v).size()); i++) {
    a = lcm(a, v[i]);
  }
  return a;
}
VI Bit2Vector(const ll bit, ll n) {
  VI s;
  for (ll i = 0; i < (ll)(n); i++)
    if (bit & (1 << i)) s.push_back(i);
  return s;
}
class GridDFS {
  using ll = long long int;

 private:
  int H, W;
  int dx[4] = {-1, 0, 0, 1};
  int dy[4] = {0, -1, 1, 0};
  struct Coordinate {
    ll y;
    ll x;
    ll depth;
  };
  vector<string> gridmap;

 public:
  int sy, sx;
  int gy, gx;

 public:
  GridDFS(vector<string> &grid) {
    gridmap = grid;
    H = grid.size();
    W = grid[0].size();
    for (int y = 0; y < H; y++) {
      for (int x = 0; x < W; x++) {
        if (grid[y][x] == 's') {
          sy = y;
          sx = x;
        }
        if (grid[y][x] == 'g') {
          gy = y;
          gx = x;
        }
      }
    }
  };
  ll search(ll dmax) {
    Coordinate start = {sy, sx, 0};
    queue<Coordinate> que;
    que.push(start);
    while (!que.empty()) {
      Coordinate now = que.front();
      que.pop();
      dmax = max(dmax, now.depth);
      for (int i = 0; i < 4; i++) {
        Coordinate next = {now.y + dy[i], now.x + dx[i], now.depth + 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;
        gridmap[next.y][next.x] = 'x';
        que.push(next);
      }
    }
    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);
  for (ll j = 0; j < (ll)(h); j++) cin >> grid[j];
  for (ll j = 0; j < (ll)(h); j++) {
    for (ll i = 0; i < (ll)(w); i++) {
      if (grid[j][i] == '#') continue;
      GridDFS 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();
}
