#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;

#define EPS (1e-7)
const long double INF = 1e17;
#define PI (acos(-1))
//const ll mod = 1000000007;
int W, H;
string field[505];
int sh, sw, gh, gw;
long double dist[505][505];
struct query {
    int h, w;
    long double cost;
    query(int _h, int _w, long double _cost) {
        h = _h;
        w = _w;
        cost = _cost;
    }
};

bool operator <(query a, query b) {
    return a.cost < b.cost;
}

bool operator >(query a, query b) {
    return a.cost > b.cost;
}

bool chmin(long double &a, long double b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

int dh[4] = {1, 0, -1, 0};
int dw[4] = {0, 1, 0, -1};

int main() {
    //cout.precision(10);
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> W >> H;
    for(int h = 1; h <= H; h++) {
        cin >> field[h];
        field[h] = "#" + field[h];
        for(int w = 1; w <= W; w++) {
            if(field[h][w] == 's') {
                sh = h;
                sw = w;
            }
            if(field[h][w] == 'g') {
                gh = h;
                gw = w;
            }
            if(field[h][w] == '.') {
            }
        }
    }
    long double ok = 1e16;
    long double ng = 0;
    priority_queue<query, vector<query>, greater<query>> que;
    for(int _ = 1; _ <= 100; _++) {
        long double mid = (ok + ng) / 2.0;
        for(int h = 1; h <= H; h++) {
            for(int w = 1; w <= W; w++) {
                dist[h][w] = INF;
                if(field[h][w] == '*') {
                    que.emplace(h, w, mid);
                    dist[h][w] = mid;
                }
            }
        }
        dist[gh][gw] = 0;
        que.emplace(gh, gw, 0);
        while(!que.empty()) {
            query now = que.top();
            que.pop();
            long double newcost = now.cost + 1.0;
            for(int k = 0; k < 4; k++) {
                int newh = now.h + dh[k];
                int neww = now.w + dw[k];
                if(field[newh][neww] == '#') {
                    continue;
                }
                if(field[newh][neww] == '*') {
                    continue;
                }
                if(chmin(dist[newh][neww], newcost)) que.emplace(newh, neww, newcost);
            }
        }
        long double distsum = 0.0;
        long double grids = 0.0;
        for(int h = 1; h <= H; h++) {
            for(int w = 1; w <= W; w++) {
                if(field[h][w] == '#') continue;
                if(field[h][w] == '*') continue;
                if(field[h][w] == 'g') continue;
                if(abs(dist[h][w] - INF) < EPS) continue;
                grids += 1.0;
                distsum += dist[h][w];
            }
        }
        /*
        cerr << "----" << mid << "----" << endl;
        for(int h = 1; h <= H; h++) {
            for(int w = 1; w <= W; w++) cerr << dist[h][w] << " ";
            cerr << endl;
        }
        */
        if(distsum / grids < mid) ok = mid;
        else ng = mid;
        if(_ == 100) {
            cout << fixed << setprecision(20) << dist[sh][sw] << endl;
            return 0;
        }
    }
    return 0;
}


Measured memory_bytes: 8624