#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
int h,w;
const int maxn=2005;
char a[maxn][maxn];
vector<pair<int,int> > e[maxn*maxn];
int dis[maxn*maxn];
bool vis[maxn*maxn];
int dr[4]={0,0,1,-1};
int dc[4]={1,-1,0,0};
int common[26];
int trans(int r,int c)
{
    return r*w+c;
}
bool inboard(int r,int c)
{
    return r>=0&&r<h&&c>=0&&c<w;
}
int main(void)
{
    cin>>h>>w;
    int s,g;
    for(int i=0;i<26;++i)
        common[i]=h*w+i;
    for(int i=0;i<h;++i)
        for(int j=0;j<w;++j)
            cin>>a[i][j];
    for(int i=0;i<h;++i)
        for(int j=0;j<w;++j)
        {
            char ch=a[i][j];
            if(ch=='#') continue;
            for(int k=0;k<4;++k)
                if(inboard(i+dr[k],j+dc[k])&&a[i+dr[k]][j+dc[k]]!='#')
                    e[trans(i,j)].push_back({trans(i+dr[k],j+dc[k]),1}),
                    e[trans(i+dr[k],j+dc[k])].push_back({trans(i,j),1});
            if(ch=='S') s=trans(i,j);
            else if(ch=='G') g=trans(i,j);
            else if(ch!='.')
                e[trans(i,j)].push_back({common[ch-'a'],0}),
                e[common[ch-'a']].push_back({trans(i,j),1});
        }
    priority_queue<pair<int,int> > pq;
    memset(dis,inf,sizeof(dis));
    memset(vis,0,sizeof(vis));
    pq.push({0,s});
    dis[s]=0;
    while(!pq.empty())
    {
        auto now=pq.top();
        pq.pop();
        if(vis[now.second]) continue;
        vis[now.second]=true;
        int id=now.second;
        int d=-now.first;
        for(auto x:e[id])
            if(dis[x.first]>dis[id]+x.second)
                dis[x.first]=dis[id]+x.second,pq.push({-dis[x.first],x.first});
    }
    if(dis[g]!=inf) cout<<dis[g]<<endl;
    else cout<<-1<<endl;
    return 0;
}

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

#define pb push_back
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define REP(i,n) for(int _n=n, i=0;i<_n;++i)
#define FOR(i,a,b) for(int64_t i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int64_t i=(a),_b=(b);i>=_b;--i)
using ull = uint64_t;
using ll = int64_t;
using PII = pair<int, int>;
using VI = vector<int>;

string to_string(string s) { return '"' + s + '"'; }
string to_string(const char* s) { return to_string((string) s); }
string to_string(bool b) { return (b ? "true" : "false"); }
template <typename A, typename B> string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }
template <typename A> string to_string(A v) {
bool first = true; string res = "{";
for (const auto &x : v) { if (!first) { res += ", "; } first = false; res += to_string(x); }
res += "}"; return res; }
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H); debug_out(T...); }
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int h, w;
    cin >> h >> w;
    vector<string> grid(h);
    vector<VI> dp(h, VI(w, -1));
    REP(i, h) cin >> grid[i];
    queue<PII> Q;
    vector<vector<PII>> letters(26);
    REP(i, h) {
    	REP(j, w) {
    		if (grid[i][j] == 'S') {
    			Q.push({i, j});
    			dp[i][j] = 0;
    		}
    		if (grid[i][j] >= 'a' && grid[i][j] <= 'z') {
    			letters[grid[i][j] - 'a'].pb({i, j});
    		}
    	}
    }
    vector<bool> F(26, false);
    int d1[4] = {1, -1, 0, 0};
    int d2[4] = {0, 0, -1, 1};
    while (!Q.empty()) {
    	auto [r, c] = Q.front();
    	Q.pop();
    	if (grid[r][c] == 'G') {
    		cout << dp[r][c] << "\n";
    		return 0;
    	}
    	if (grid[r][c] >= 'a' && grid[r][c] <= 'z' && !F[grid[r][c] - 'a']) {
    		F[grid[r][c] - 'a'] = true;
    		for (auto p : letters[grid[r][c] - 'a']) {
    			if (p.first == r && p.second == c) continue;
    			if (dp[p.first][p.second] != -1) continue;
    			Q.push({p.first, p.second});
    			dp[p.first][p.second] = dp[r][c] + 1;
    		}
    	}
    	FOR(i, 0, 3) {
    		int rr = r + d1[i];
    		int cc = c + d2[i];
    		if (rr < 0 || rr >= h || cc < 0 || cc >= w) continue;
    		if (grid[rr][cc] == '#') continue;
    		if (dp[rr][cc] != -1) continue;
    		dp[rr][cc] = dp[r][c] + 1;
    		Q.push({rr, cc});
    	}
    }
    cout << "-1\n";
}