#include<bits/stdc++.h>
#include<bits/extc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using namespace __gnu_pbds;
#ifndef DEBUG
#define cerr while(false) cerr
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define priority_queue std::priority_queue
#define F first
#define S second

int dx[]={1, -1, 0, 0};
int dy[]={0, 0, 1, -1};
vector<pii>adj[5000005];
char a[2005][2005];
int INF=1e9;
ll dist[5000005];
int get(int x, int y){
	if(a[x][y]=='S') return 0;
	if(a[x][y]=='G') return 1;
	return x*2005+y+2;
}
void dijkstra(int src){
	for(int i=0;i<5000005;i++) dist[i]=INF;
	priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;
	dist[src]=0;
	pq.push({0, src});
	while(!pq.empty()){
		auto [w, x]=pq.top(); pq.pop();
		if(dist[x]<w) continue;
		for(auto [y, cw]: adj[x]){
			if(dist[y]>w+cw){
				dist[y]=w+cw;
				pq.push({dist[y], y});
			}
		}
	}
}
signed main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int h, w;
	cin>>h>>w;
	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++){
			if(a[i][j]=='#') continue;
			for(int k=0;k<4;k++){
				int ci=i+dx[k], cj=j+dy[k];
				if(ci>=0 && ci<h && cj>=0 && cj<w && a[ci][cj]!='#'){
					//cout<<get(i, j)<<" "<<get(ci, cj)<<" "<<2<<endl;
					adj[get(i, j)].push_back({get(ci, cj), 2});
				}
			}
			if(a[i][j]>='a' && a[i][j]<='z'){
				int c=4500000+(int)(a[i][j]-'a');
				adj[get(i, j)].push_back({c, 1});
				adj[c].push_back({get(i, j), 1});
			}
		}
	}
	dijkstra(0);
	cout<<(dist[1]==INF ? -1 : dist[1]/2)<<endl;
}
// g++ -std=c++11 a.cpp
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<unordered_map>
#include<utility>
#include<cmath>
#include<random>
#include<cstring>
#include<queue>
#include<stack>
#include<bitset>
#include<cstdio>
#include<sstream>
#include<random>
#include<iomanip>
#include<assert.h>
#include<typeinfo>
#define loop(i,a,b) for(int i=a;i<b;i++)
#define rep(i,a) loop(i,0,a)
#define FOR(i,a) for(auto i:a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
#define show1d(v) {rep(_,v.size())cout<<" "<<v[_];cout<<endl;}
#define show2d(v) {rep(__,v.size())show1d(v[__]);}
using namespace std;
//kaewasuretyuui
typedef long long ll;
#define int ll
typedef int Def;
typedef pair<Def,Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def,pii> pip;
typedef vector<pip>vip;
#define mt make_tuple
typedef tuple<int,int,int> tp;
typedef vector<tp> vt;
typedef vector<vt>vvt;
template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;}
template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;}
const double PI=acos(-1);
const long double EPS=1e-9;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9+10;
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
#define yes cout<<"Yes\n"
#define no cout<<"No\n"

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n,m;
	cin>>n>>m;
	vs in(n);
	rep(i,n)cin>>in[i];
	vvp w(26);
	vvi dp(n,vi(m,inf));
	vi used(26);
	queue<pii>q;
	rep(i,n)rep(j,m){
		if(in[i][j]=='S'){
			dp[i][j]=0;
			q.push({i,j});
		}
		if(islower(in[i][j])){
			w[in[i][j]-'a'].pb({i,j});
		}
	}
	while(!q.empty()){
		int x=q.front().first;
		int y=q.front().second;
		q.pop();
		if(in[x][y]=='G'){
			cout<<dp[x][y]<<endl;
			return 0;
		}
		rep(i,4){
			int nx=x+dx[i];
			int ny=y+dy[i];
			if(nx<0||ny<0||nx>=n||ny>=m)continue;
			if(in[nx][ny]=='#')continue;
			if(dp[nx][ny]!=inf)continue;
			dp[nx][ny]=dp[x][y]+1;
			q.push({nx,ny});
		}
		if(islower(in[x][y])){
			int a=in[x][y]-'a';
			if(used[a])continue;
			rep(j,w[a].size()){
				pii ax=w[a][j];
				if(dp[ax.first][ax.second]-inf)continue;
				dp[ax.first][ax.second]=dp[x][y]+1;
				q.push(ax);
			}
			used[a]=1;
		}
	}
	cout<<-1<<endl;
}
