#include <queue>
#include <iomanip>
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <tuple>

#define REP(i,n) for(int i=0;i<(int)(n);i++)

using namespace std;

typedef long long Weight;

const Weight INF = 1000000000000ll;

struct Edge{
  int src, dest; Weight weight;
  bool operator < (const Edge &rhs) const {return weight > rhs.weight;}
};

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
// The costs of edges must be 0 or 1 (Verified: TCO 2014 Round 2C Medium)
void bfs01(Graph &g, vector<Weight> &d, int s) {
  fill(d.begin(), d.end(), INF);
  d[s] = 0;
  typedef pair<Weight,int> P;
  queue<P> que, zero;
  que.push(P(0, s));
  while (!zero.empty() || !que.empty()) {
    P top = zero.empty() ? que.front() : zero.front();
    if (zero.empty()) que.pop(); else zero.pop();
    Weight dist = top.first; int v = top.second;
    if (d[v] < dist) continue;
    REP(i, g[v].size()) {
      Edge e = g[v][i];
      if (d[e.dest] > d[v] + e.weight) {
        d[e.dest] = d[v] + e.weight;
        if (e.weight) que.push(P(d[e.dest], e.dest));
        else zero.push(P(d[e.dest], e.dest));
      }
    }
  }
}

bool is_mbl(char c){
  return c=='.'||c=='s'||c=='g'||c=='*';
}

bool is_bembl(char c){
  return c=='.'||c=='s';
}

int main() {
  int w,h;
  cin>>w>>h;
  vector<string> t(h);
  REP(i,h)cin>>t[i];
  int s,gix;
  REP(i,h)REP(j,w){
    if(t[i][j]=='s'){
      s=i*w+j;
    }else if(t[i][j]=='g'){
      gix=i*w+j;
    }
  }
  Graph g(h*w+1);
  REP(i,h)REP(j,w){
    if(!is_mbl(t[i][j]))continue;
    int di[]={1,0,-1,0};
    int dj[]={0,1,0,-1};
    int six = i*w+j;
    REP(k,4){
      int ni=i+di[k];
      int nj=j+dj[k];
      if(ni<0||nj<0||ni>=h||nj>=w)continue;
      if(!is_bembl(t[ni][nj]))continue;
      int tix = ni*w+nj;
      g[six].push_back({six,tix,1});
    }
    if(t[i][j]=='*'){
      g[h*w].push_back({h*w,six,0});
    }
  }
  Array dg(h*w+1);
  Array ds(h*w+1);
  bfs01(g, dg, gix);
  bfs01(g, ds, h*w);
  long double v=1e+10;
  long double ex_spr = 0;
  while(v > 1e-14){
    long double dist_sum = 0;
    int cnt=0;
    REP(i,h*w){
      if(!is_bembl(t[i/w][i%w]))continue;
      dist_sum += min((long double)(dg[i]), ds[i] + ex_spr + v);
      ++cnt;
    }
    if (ex_spr + v < (dist_sum/cnt)) {
      ex_spr += v;
    }
    v /= 2.0;
  }
  cout << setprecision(14) << fixed << min((long double)(dg[s]), ds[s] + ex_spr) << endl;
  return 0;
}