#include<bits/stdc++.h>
#define re register
#define in inline
#define ll int
using namespace std;
char rbuf[10000002];
int pt;
in char gc(){
    return getchar();
}
in int read(){
    re int t=0;
    re char v=gc();
    while(v<'0')v=gc();
    while(v>='0'){
        t=(t<<3)+(t<<1)+(v^48);
        v=gc();
    }
    return t;
}
struct edge{
    int to,next,w;
}e[3002*3002*2];
int n,m,cnt,k,l[15],r[15],head[3002*3002],a,b,c,pl[32],w[15];
struct node{
    int pos;
    ll dis;
    bool operator <(const node x)const{
        return dis>x.dis;
    }
}h[3002*3002];
priority_queue <node> q;
inline ll M(re ll x,re ll y){
    return (x<y)?(x):(y);
}
inline void dis(re int s){for(re int i=1;i<=n*m+26;++i)h[i].pos=i,h[i].dis=0x7fffffff;
    h[s].dis=0;
    q.push(h[s]);
    while(!q.empty()){
        while((h[q.top().pos].dis<q.top().dis)){q.pop();if(q.empty())break;
        }
        if(q.empty())break;
        node tmp=q.top();
        q.pop();
        for(re int i=head[tmp.pos];i;i=e[i].next){
            if((tmp.dis+e[i].w)<h[e[i].to].dis){
                h[e[i].to].dis=tmp.dis+e[i].w;
                q.push(h[e[i].to]);
            }
        }
     
    }
}
inline void add(re int x,re int y,re int z){
    e[++cnt].to=y;
    e[cnt].w=z;
    e[cnt].next=head[x];
    head[x]=cnt;
}
char s[3002][3002];
signed main(){
//  freopen("test.in","r",stdin);
//  freopen("test.out","w",stdout);
    n=read();
    re int ss,tt;
    m=read();
   for(re int i=1;i<=n;++i)scanf("%s",s[i]+1);
   for(re int i=1;i<=n;++i){
   	for(re int j=1;j<=m;++j){
   		if(s[i][j]!='#'&&s[i+1][j]!='#'&&i!=n){
   			add((i-1)*m+j,i*m+j,1);
   			add(i*m+j,(i-1)*m+j,1);
		   }
	   if(s[i][j]!='#'&&s[i][j+1]!='#'&&j!=m){
   			add((i-1)*m+j,(i-1)*m+j+1,1);
   			add((i-1)*m+j+1,(i-1)*m+j,1);
		   }
	   if(s[i][j]>='a'&&s[i][j]<='z'){
	   	add((i-1)*m+j,n*m+s[i][j]-'a'+1,1);
	   	add(n*m+s[i][j]-'a'+1,(i-1)*m+j,0);
	   }
	   if(s[i][j]=='S')ss=(i-1)*m+j;
	   if(s[i][j]=='G')tt=(i-1)*m+j;
	   }
	   }
   dis(ss);
   if(h[tt].dis<=1e9)
 printf("%d ",h[tt].dis);
 else puts("-1");
}
#include"bits/stdc++.h"
using namespace std;
const int N=2100;
char a[N][N];
vector<pair<int,int>> c[26];
int dx[]={1,-1,0,0};
int dy[]={0,0,-1,1};
int d[N][N];
int n,m;
const int inf=1e9;
bool vis[26];
bool ok(int x,int y){
	return (x<=n and y<=m and x>=1 and y>=1);
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)d[i][j]=inf;
	for(int i=1;i<=n;i++){
		scanf("%s", a[i]+1);
	}
	int sx=-1,sy=-1,gx=-1,gy=-1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[i][j]<='z' and a[i][j]>='a')c[a[i][j]-'a'].push_back({i,j});
			if(a[i][j]=='S'){sx=i;sy=j;}
			if(a[i][j]=='G'){gx=i;gy=j;}
		}
	}


	deque<pair<int,int>> q;
	q.push_back({sx,sy});
	d[sx][sy]=0;

	while(!q.empty()){

		auto p=q.front();
		q.pop_front();
		int cur=d[p.first][p.second];
		int curc=a[p.first][p.second];
		if(curc<='z' and curc>='a' and !vis[curc-'a']){
				
				for(auto pp:c[curc-'a']){
					if(d[pp.first][pp.second]>1+cur){

						q.push_front({pp.first,pp.second});
						d[pp.first][pp.second]=1+cur;
					}
				}
				vis[curc-'a']=1;
			}

		for(int k=0;k<4;k++){
			int nx=p.first+dx[k];
			int ny=p.second+dy[k];
			if(!ok(nx,ny))continue;
			if(a[nx][ny]=='#')continue;
		
			if(d[nx][ny]>1+cur)
			{
				d[nx][ny]=1+cur;
				q.push_back({nx,ny});
			}
		}

	}


	if(d[gx][gy]==inf)puts("-1");
	else cout<<d[gx][gy]<<"\n";
	
}

