// Fearless
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define pii pair <int, int>
#define pll pair <long long, long long>
#define PI (2.0 * acos(0.0))
#define testcase ll T; cin >> T; for (ll tc = 1; tc <= T; tc++)
#define info pair<int, pii>
#define mkp make_pair
const long long M = 1e5 + 10, M2 = 1e6 + 10, oo = 1e9 + 7;
int dis[2002][2002], vis[2002][2002], cvis[30];
vector < pii > adj[2002][2002];
vector < pii > pos[30];
int fx[4] = {0, 1};
int fy[4] = {1, 0};
void solve () {
	int r, c;
	pii src, tr;
	cin >> r >> c;
	char str[r + 2][c + 2];
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			cin >> str[i][j];
		}
	}
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++) {
			if (str[i][j] == '#') continue;
			if (str[i][j] >= 'a' && str[i][j] <= 'z') {
				pos[str[i][j] - 'a'].pb(pii(i, j));
			}
			if (str[i][j] == 'S') {
				src = pii(i, j);
			}
			if (str[i][j] == 'G') {
				tr = pii(i, j);
			}
			for (int k = 0; k < 2; k++) {
				if (i + fx[k] < 0 || i + fx[k] >= r || j + fy[k] < 0 || j + fy[k] >= c) continue;
				if (str[i + fx[k]][j + fy[k]] == '#') continue;
				pii p1 = pii(i, j), p2 = pii(i + fx[k], j + fy[k]);
				adj[i][j].pb(p2);
				adj[i + fx[k]][j + fy[k]].pb(p1);
			}
		}
	}
	queue < pii > q;
	q.push(src);
	while (!q.empty()) {
		pii u = q.front();
		q.pop();
		int ux = u.first, uy = u.second;
		if (str[ux][uy] >= 'a' && str[ux][uy] <= 'z' && cvis[str[ux][uy] - 'a'] == 0) {
			cvis[str[ux][uy] - 'a'] = 1;
			for (pii v : pos[str[ux][uy] - 'a']) {
				int vx = v.first, vy = v.second;
				//cout << vx << " this " << vy << endl;
				if (vis[vx][vy]) continue;
				dis[vx][vy] = dis[ux][uy] + 1;
				vis[vx][vy] = 1;
				q.push(v);
			}
		}
		//cout << adj[ux][uy].size() << " size " << endl;
		for (pii v : adj[ux][uy]) {
			int vx = v.first, vy = v.second;
			//cout << vx << " " << vy << " now " << vis[vx][vy] << endl;
			if (vis[vx][vy]) continue;
			dis[vx][vy] = dis[ux][uy] + 1;
			vis[vx][vy] = 1;
			q.push(v);
		}
	}
	if (!vis[tr.first][tr.second]) cout << -1 << endl;
	else cout << dis[tr.first][tr.second] << endl;
}
int main () {
    //freopen("E:/newts/in.txt", "r", stdin);
    //freopen("E:/newts/out.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //testcase {
        solve ();
    //}
    return 0;
}



/**
 *    Coded by : lucky_21
 *               --------Lokesh Singh
**/

#include<bits/stdc++.h>
using namespace std;

#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template<class T> using oset=tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

#define     F           first
#define     S           second
#define     pb          push_back
#define     lb          lower_bound
#define     ub          upper_bound
#define     pii         pair<int,int>
#define     all(x)      x.begin(),x.end()
#define     fix         fixed<<setprecision(10)
#define     rep(i,a,b)  for(int i=int(a);i<=int(b);i++)
#define     repb(i,b,a) for(int i=int(b);i>=int(a);i--)
#define     FastIO      ios_base::sync_with_stdio(0),cin.tie(0)

typedef double db;
typedef long long ll;

const int N=2005;
const int mod=1e9+7;

int h,w,dis[N][N];
vector<pii>v[26];
char g[N][N];
bool inside(int x,int y){
    if(g[x][y]=='#') return 0;
    if(x>0 and y>0 and x<=h and y<=w) return 1;
    return 0;
}
int bfs(pii p){
    queue<pii>q;
    q.push(p);
    rep(i,1,h) rep(j,1,w) dis[i][j]=1e9;
    dis[p.F][p.S]=0;
    while(!q.empty()){
        p=q.front();
        q.pop();
        if(g[p.F][p.S]=='G') return dis[p.F][p.S];
        if(islower(g[p.F][p.S])){
            for(pii t:v[g[p.F][p.S]-'a']) if(t!=p and dis[t.F][t.S]>dis[p.F][p.S]+1){
                q.push(t);
                dis[t.F][t.S]=dis[p.F][p.S]+1;
            }
            v[g[p.F][p.S]-'a'].clear();
        }
        rep(i,-1,1) rep(j,-1,1) if(abs(i)+abs(j)<=1 and dis[p.F+i][p.S+j]>dis[p.F][p.S]+1 and inside(p.F+i,p.S+j)){
            dis[p.F+i][p.S+j]=dis[p.F][p.S]+1;
            q.push({p.F+i,p.S+j});
        }
    }
    return -1;
}
signed main(){
    FastIO;
    cin>>h>>w;
    pii st;
    rep(i,1,h) rep(j,1,w){
        cin>>g[i][j];
        if(islower(g[i][j])) v[g[i][j]-'a'].pb({i,j});
        if(g[i][j]=='S') st={i,j};
    }
    cout<<bfs(st);
    return 0;
}
