#include <bits/stdc++.h>
using namespace std;
const long long int INF = 1e18;

int n;
struct edge{ int to; long long int cost; };
vector<vector<edge>> graph;

vector<long long int> Dijkstra(int s){
    priority_queue<pair<long long int, int>,
    vector<pair<long long int, int>>,
    greater<pair<long long int, int>>> pq;
    vector<long long int> d(n, INF);
    d[s] = 0;
    pq.push({0,s});

    while(pq.empty() == false){
        auto x = pq.top();
        pq.pop();

        if(x.first > d[x.second]) continue;

        for(edge e : graph[x.second]){
            if(d[e.to] > d[x.second] + e.cost){
                d[e.to] = d[x.second] + e.cost;
                pq.push({d[e.to], e.to});
            }
        }
    }
    return d;
}

int h, w;
int id(int x, int y){
    return x * w + y;
}

int main(){
    cin >> h >> w;

    vector<string> a(h);
    for(int i=0; i<h; i++){
        cin >> a[i];
    }

    vector<int> dx = {1, 0, -1, 0};
    vector<int> dy = {0, 1, 0, -1};

    n = h*w + 26;
    graph.resize(n);
    int s = -1;
    int g = -1;

    for(int x=0; x<h; x++){
        for(int y=0; y<w; y++){
                 if(a[x][y] == '#') continue;
            else if(a[x][y] == 'S') s = id(x,y);
            else if(a[x][y] == 'G') g = id(x,y);
            else if(a[x][y] == '.') ;
            else{
                int teleporter = h*w + (a[x][y] - 'a');
                graph[id(x,y)].push_back({teleporter,1});
                graph[teleporter].push_back({id(x,y),1});
            }

            for(int i=0; i<4; i++){
                if(0 <= x+dx[i] && x+dx[i] < h
                && 0 <= y+dy[i] && y+dy[i] < w
                && a[x+dx[i]][y+dy[i]] != '#') graph[id(x,y)].push_back({id(x+dx[i], y+dy[i]),2});
            }
        }
    }

    vector<long long int> d = Dijkstra(s);
    if(d[g] == INF) d[g] = -2;
    cout << d[g] / 2 << endl;
    return 0;
}
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
#define FOR(i, n) for(int (i)=0; (i)<(n); (i)++)
#define FOR1(i, n) for(int (i)=1; (i)<=(n); (i)++)
#define FORI(i, n) for(int (i)=n-1; (i)>=0; (i)--)
template<class T, class U> void umin(T& x, const U& y){ x = min(x, (T)y);}
template<class T, class U> void umax(T& x, const U& y){ x = max(x, (T)y);}
template<class T, class U> void init(vector<T> &v, U x, size_t n) { v=vector<T>(n, (T)x); }
template<class T, class U, typename... W> void init(vector<T> &v, U x, size_t n, W... m) { v=vector<T>(n);  for(auto& a : v) init(a, x, m...); }

int h, w, a, b;
int sol = 0;
vector<vector<int>> X;
void bt(int k, int aa){
    if (k == h*w){
        sol += aa == a+1;
        return;
    }
    int r = k/w;
    int c = k%w;

    if (X[r][c]) {
        bt(k + 1, aa);
        return;
    }

    if (aa<=a && r+1 < h && !X[r+1][c]){
        X[r][c] = X[r+1][c] = aa;
        bt(k+1, aa+1);
        X[r][c] = X[r+1][c] = 0;
    }

    if (aa<=a && c+1 < w && !X[r][c+1]){
        X[r][c] = X[r][c+1] = aa;
        bt(k+1, aa+1);
        X[r][c] = X[r][c+1] = 0;
    }

    X[r][c] = h*w;
    bt(k+1, aa);
    X[r][c] = 0;
}

int main(int argc, char** argv) {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cout << setprecision(15);
    if (argc == 2 && atoi(argv[1]) == 123456789) freopen("d:\\code\\cpp\\contests\\stdin", "r", stdin);
    cin >> h >> w >> a >> b;
    init(X, 0, h, w);
    bt(0, 1);
    cout << sol << endl;
    if (argc == 2 && atoi(argv[1]) == 123456789) cout << clock()*1.0/CLOCKS_PER_SEC << " sec\n";
    return 0;
}

