#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#define N 2005
using namespace std;

int n, m, d[N][N], cnt[30];
vector<int> er[30], ec[30];
int dr[4] = {-1, 0, 0, 1}, dc[4] = {0, -1, 1, 0};
bool v[N][N];
int va[30];
char a[N][N];
queue<int> qr, qc, qs;
void f(int p, int q, int w) {
	int t;
	if (v[p][q]) return;
	t = a[p][q] - 'a';
	if (t >= 0 && t <= 25 && va[t] == 0) va[t] = w;
	if (t >= 0 && t <= 25 && w - va[t] >= 2) return;
//	printf("%d %d\n", p, q);
	v[p][q] = 1;
	qr.push(p);
	qc.push(q);
	qs.push(w);
}
int main()
{
	int i, j, t, rr, cc, tr, ts, tc, sr, sc;
	cin >> n >> m;
//	for (i = 0; i <= n + 1; i++) {
//		for (j = 0; j <= m + 1; j++) a[i][j] = '#';
//	}
	for (i = 1; i <= n; i++) {
		scanf ("%s", &a[i][1]);
	}
	for (i = 0; i <= n + 1; i++) {
		a[i][0] = a[i][m + 1] = '#';
	}
	for (i = 0; i <= m + 1; i++) {
		a[0][i] = a[n + 1][i] = '#';
	}
	for (i = 1; i <= n; i++) {
		for (j = 1; j <= m; j++) {
			if (a[i][j] == '#' || a[i][j] == '.' ||a[i][j] == 'G') continue;
			if (a[i][j] == 'S') {
				sr = i;
				sc = j;
			} else {
				t = a[i][j] - 'a';
				cnt[t]++;
				er[t].push_back(i);
				ec[t].push_back(j);
				d[i][j] = cnt[t];
			}
		}
	}
	f(sr, sc, 0);
	while (!qr.empty()) {
		tr = qr.front(); qr.pop();
		tc = qc.front(); qc.pop();
		ts = qs.front(); qs.pop();
		if (a[tr][tc] == 'G') {
			cout << ts << endl;
			return 0;
		}
		t = a[tr][tc] - 'a';
		if (ts - va[t] == 0) {
			if (a[tr][tc] - 'a' >= 0 && a[tr][tc] - 'a' <= 25) {
				for (i = 0; i < er[t].size(); i++) {
					f(er[t][i], ec[t][i], ts +1);
				}
			}
		}
		for (i = 0; i < 4; i++) {
			rr = tr + dr[i];
			cc = tc + dc[i];
			if (a[rr][cc] == '#') continue;
			f(rr, cc, ts + 1);
		}
	}
	cout << -1 << endl;
    return 0;
}

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<utility>
#include<set>
#include<stack>
#include<list>
#include<deque>
#include<bitset>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<climits>
#include<cmath>
#include<cctype>


#define pb push_back
#define mp make_pair
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ren(i,a,b) for(int i=a;i>=b;i--)
#define ff first
#define ss second
#define pll pair<long long int,long long int>
#define pii pair<int,int>
#define vll vector<long long int>
#define vii vector<int>
#define gi(n) scanf("%d",&n)
#define gll(n) scanf("%lld",&n)
#define gstr(n) scanf("%s",n)
#define gl(n) cin >> n
#define oi(n) printf("%d",n)
#define oll(n) printf("%lld",n)
#define ostr(n) printf("%s",n)
#define ol(n) cout << n
#define os cout<<" "
#define on cout<<"\n"
#define o2(a,b) cout<<a<<" "<<b
#define all(n) n.begin(),n.end()
#define present(s,x) (s.find(x) != s.end())
#define cpresent(s,x) (find(all(s),x) != s.end())
#define tr(container, it) for(__typeof(container.begin()) it = container.begin(); it != container.end(); it++)
using namespace std;

typedef unsigned long long int ull;
typedef long long int ll;
typedef long double ld;
typedef vector<vector<ll> > mat;

string s[2005];
int n,m,dis[2005][2005],used[26];

bool good(int i,int j)
{
	if(i<0||i>=n||j<0||j>=m)return 0;
	if(dis[i][j]>-1)return 0;
	if(s[i][j]=='#')return 0;
	return 1;
}

int main()
{ios_base::sync_with_stdio(false);
cin>>n>>m;
rep(i,0,n-1)cin>>s[i];
rep(i,0,n-1)rep(j,0,m-1)dis[i][j]=-1;

queue<pii> q;

rep(i,0,n-1)rep(j,0,m-1)
{
	if(s[i][j]=='S')
	{
		q.push({i,j});
		dis[i][j]=0;
	}
}

while(!q.empty())
{
	pii p=q.front();
	q.pop();
	char c=s[p.ff][p.ss];
	int d=dis[p.ff][p.ss];
	if(c>='a'&&c<='z')
	{
		if(used[c-'a']==0)
		{
			used[c-'a']=1;
			rep(i,0,n-1)rep(j,0,m-1)
			{
				if(dis[i][j]==-1&&s[i][j]==c)
				{
					dis[i][j]=1+d;
					q.push({i,j});
				}
			}
		}
	}
	if(good(p.ff-1,p.ss))
	{
		q.push({p.ff-1,p.ss});
		dis[p.ff-1][p.ss]=1+d;
	}
	if(good(p.ff+1,p.ss))
	{
		q.push({p.ff+1,p.ss});
		dis[p.ff+1][p.ss]=1+d;
	}
	if(good(p.ff,p.ss-1))
	{
		q.push({p.ff,p.ss-1});
		dis[p.ff][p.ss-1]=1+d;
	}
	if(good(p.ff,p.ss+1))
	{
		q.push({p.ff,p.ss+1});
		dis[p.ff][p.ss+1]=1+d;
	}
}
rep(i,0,n-1)
{
	rep(j,0,m-1)
	{
		if(s[i][j]=='G')ol(dis[i][j]);
	}
}
return 0;
}

