#include<iostream>
#include<climits>
#include<cstdio>
#include<queue>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
typedef long long ll;
const int N = 500;
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
const ll inf = 1LL<<60;
char m[N][N+1];
ll dcost[N][N];//ç´æ¥ã´ã¼ã«ã¾ã§è¡ãã³ã¹ã
ll scost[N][N];//ãããä½¿ã£ãæã®ã³ã¹ã
void bfs(int r,int c,char s,ll cost[N][N]){
  queue<int> Q;
  rep(i,r)rep(j,c)
    if (m[i][j] == s)cost[i][j] = 0,Q.push(i*c+j);
    else cost[i][j] = inf;
  while(!Q.empty()){
    int y = Q.front()/c,x=Q.front()%c;Q.pop();
    //    cout << y <<" " << x << endl;
    rep(i,4){
      int ney = y+dy[i],nex = x+dx[i];
      if (m[ney][nex] == '*' || m[ney][nex] == 'g' || m[ney][nex] == '#' || cost[ney][nex] != inf)continue;
      cost[ney][nex] = cost[y][x] + 1;
      Q.push(ney*c+nex);
    }
  }
}

//brute force,ã¨ããããåæããã¾ã§åãã¦ã¿ã
//å¥åãgs*ã¿ãããªã®ãæ¥ãã¨è½ã¡ãå¯è½æ§ããã
double exp[N][N];
double bf(int r,int c){
  double e=0;//æå¾å¤ã®ç·åãæã£ã¦ããã¨å½¹ã«ç«ã¤
  double pos = 0;//ããã§è¡ãå¯è½æ§ã®ããå ´æã®æ°
  int sy,sx;
  rep(i,r){
    rep(j,c){
      if (m[i][j] == '*' || m[i][j] == 'g' || m[i][j] == '#')continue;
      exp[i][j] = dcost[i][j];
      e += dcost[i][j];
      pos++;
      if (m[i][j] == 's')sy = i,sx = j;
    }
  }


  double L = 0,R=1e20;
  double ans = -1;
  rep(i,300){
    double mid = (L+R)/2.;
    double newe = 0;
    rep(i,r){
      rep(j,c){
	if (m[i][j] == 'g' || m[i][j] == '#' || m[i][j] == '*')continue;
	double tmp = dcost[i][j];
	double tmp2 = scost[i][j] + mid/pos;
	newe += min(tmp,tmp2);
      }
    }

    //cout <<"owari " << newe <<" " << L << " " << mid <<" " << R << endl;
    if (newe < mid){//äºæ³ããå°ããã£ã
      ans = mid;
      R = mid - 1e-10;
    }else {//äºæ³ããå¤§ããã£ã
      L = mid + 1e-10;
    }
  }
  //cout << ans<< " " << ans/pos << endl;
  return  min((double)dcost[sy][sx],scost[sy][sx]+ans/pos);

  /*
  while(true){
    bool isupdate = false;
    double newe = 0;
    rep(i,r){
      rep(j,c){
	if (m[i][j] == 'g' || m[i][j] == '#')continue;//ããã¯èããªãã
	double tmp = dcost[i][j];
	double tmp2 = scost[i][j] + (e)/(pos);
	if (exp[i][j] > min(tmp,tmp2)){
	  isupdate = true;
	  e -= exp[i][j];
	  exp[i][j] = min(tmp,tmp2);
	  e += exp[i][j];
	}
	newe += exp[i][j];
      }
    }
    e = newe;
    cout <<"debug " << endl;
    rep(i,r){
      rep(j,c){
	printf("%.3lf ",exp[i][j]);
      }
      printf("\n");
    }
    cout <<"--------------==" << endl;

    if (!isupdate)break;
  }

  double hoge = 0;
  rep(i,r){
    rep(j,c){
      if (m[i][j] == '#' || m[i][j] == 'g' || m[i][j] == '*')continue;
      hoge += min((double)dcost[i][j],scost[i][j] + e/pos);
      cout << min((double)dcost[i][j],scost[i][j] + e/pos) <<" " ;
    }
    cout << endl;
  }
  cout <<"hoge " << e <<" " << hoge/pos << endl;
  */
  rep(i,r)rep(j,c)if (m[i][j] == 's')return exp[i][j];
}


main(){
  int r,c;
  while(cin>>c>>r && r){
    rep(i,r)cin>>m[i];
    bfs(r,c,'*',scost);
    bfs(r,c,'g',dcost);
    printf("%.12lf\n",bf(r,c));
  }
}

Measured memory_bytes: 7072