#include <iostream>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <map>
#include <utility>
#include <list>
#include <climits>
#include <bitset>
#include <numeric>
#include <cmath>
#include <queue>

using namespace std;

#define rep(i, n) for(int i = 0; i < n; i++)
#define repi(i, n) for(auto i = (n).begin(); i != (n).end(); i++)
#define in_arr(type, a, n) copy_n(istream_iterator<type>(cin), n, (a).begin());

class Pos{
public:
    int x, y;
    Pos(int i, int j){
        x = i;
        y = j;
    }
};

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
typedef pair<double,double> pdd;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<string> vs;
typedef vector<P> vp;
typedef vector<vp> vvp;
typedef vector<pll> vpll;
typedef pair<int,P> pip;
typedef vector<pip> vip;
const int inf=1<<30;
const ll INF=1ll<<60;
const double pi=acos(-1);
const double eps=1e-9;
const ll mod=1e9+7;
const int dx[9]={0,1,0,-1, -1, -1, 1, 1, 0},dy[9]={1,0,-1,0, -1, 1, -1, 1, 0};

class Graph{
private:
    int n;
    vvp g;
public:
    int DIJ(int s,int t){
        priority_queue<P> q;
        vi d(n,inf);
        d[s]=0;
        q.push({0,s});
        while(!q.empty()){
            P p=q.top();
            q.pop();
            int v=p.second;
            if(d[v]<-p.first) continue;
            for(auto i:g[v]){
                int u=i.first,D=d[v]+i.second;
                if(d[u]>D){
                    d[u]=D;
                    q.push({-D,u});
                }
            }
        }
        return d[t];
    }
    Graph(int v){
        n=v;
        g=vvp(v);
    }
    void add_edge(int s,int t,int c){
        g[s].push_back({t,c});
    }
};

int main(){
    int h, w, a, b;
    cin >> h >> w >> a >> b;
    vector<string> c(h);
    vector<vector<bool>> visited(h);
    generate(visited.begin(), visited.end(), [w](){ return vector<bool>(w, false); });
    in_arr(string, c, h);
    int sx, sy, gx, gy;
    rep(i, h){
        rep(j, w){
            if(c[i][j] == 's'){
                sx = i;
                sy = j;
                c[i][j] = '.';
            }else if(c[i][j] == 'g'){
                gx = i;
                gy = j;
                c[i][j] = '.';
            }
        }
    }
    
    Graph g = Graph(h * w);
    rep(i, h){
        rep(j, w){
            bool can_ab = true;
            rep(k, 9){
                int x = i + dx[k];
                int y = j + dy[k];
                if(x < 0 || x >= h || y < 0 || y >= w){
                    continue;
                }
                if(c[x][y] == '*'){
                    can_ab = false;
                    break;
                }
            }
            
            rep(k, 4){
                int x = i + dx[k];
                int y = j + dy[k];
                if(x < 0 || x >= h || y < 0 || y >= w){
                    continue;
                }
                if(c[x][y] != '#'){
                    g.add_edge(i * w + j, x * w + y, a);
                }
            }
            if(!can_ab){
                continue;
            }
            rep(k, 8){
                int x = i + dx[k];
                int y = j + dy[k];
                if(x < 0 || x >= h || y < 0 || y >= w || c[x][y] != '#'){
                    continue;
                }
                if(abs(dx[k]) + abs(dy[k]) < 2){
                    g.add_edge(i * w + j, x * w + y, a + b);
                }else{
                    g.add_edge(i * w + j, x * w + y, 2 * a + b);
                }
            }
        }
    }
    int ans = g.DIJ(sx * w + sy, gx * w + gy);
    if(ans == inf){
        cout << "INF" << endl;
    }else{
        cout << ans << endl;
    }
    return 0;
}

