

//BELIEVE IN YOURSELF
//next_permutation

#include<bits/stdc++.h>
#define ll long long int
#define ld long double
#define pb push_back
#define pob pop_back
#define vi vector<ll>
#define mp make_pair
#define sz size()
#define rep1(i,n) for(ll i=1;i<=n;i++)
#define rep(i,n) for(ll i=0;i<n;i++)
#define fast ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define maxx 100005
#define sec second
#define fi first
#define be begin()
#define en end()
#define sortv(v) sort(v.begin(),v.end());
#define sortr(v) sort(v.rbegin(),v.rend());
#define w() ll _;cin>>_;while(_--)
#define edge pair<ll,ll>
#define pq priority_queue<ll>
#define mod 1000000007
#define Endl "\n"
#define cy cout<<"YES"<<endl;
#define cn cout<<"NO"<<endl;
#define lb(v,x) std::lower_bound(v.begin(),v.end(),x)
#define ub(v,x) std::upper_bound(v.begin(),v.end(),x)

using namespace std;

ll dx[]={-1,0,1,0};
ll dy[]={0,-1,0,1};

ll n,m;

bool isvalid(ll x,ll y)
{
	if(x>=0 && y>=0 && x<n && y<m)
	{
		return true;
	}
	return false;
}

int main()
{
		fast;

		cin>>n>>m;
		ll i,j;
		string s;
		vector<string>g;
		
		for(i=0;i<n;i++)
		{
			cin>>s;
			g.pb(s);
		}		
		
		ll a[n+1][m+1];
//		ll vis[n+1][m+1];
		
		
		ll inf=1e17;
		ll sx=0,sy=0,ex=0,ey=0;
		
		vector<vector<pair<ll,ll> > >tp(26);
		
		for(i=0;i<n;i++)
		{
			for(j=0;j<m;j++)
			{
				a[i][j]=inf;
				if(g[i][j]=='S')
				{
					a[i][j]=0;
					sx=i;
					sy=j;
				}
				if(g[i][j]=='G')
				{
					ex=i;
					ey=j;
				}
				if(g[i][j]>='a' && g[i][j]<='z')
				{
					char c=g[i][j];
					tp[c-'a'].pb(mp(i,j));
				}
			}
		}
		
		
		queue<pair<ll,ll> >q;
		
		q.push(mp(sx,sy));
		
		while(!q.empty())
		{
			ll x,y;
			pair<ll,ll>now =q.front();
			q.pop();
			
			x=now.fi;
			y=now.sec;
			
			for(i=0;i<4;i++)
			{
				ll nx,ny;
				pair<ll,ll>next = mp(x+dx[i],y+dy[i]);
				
				nx=next.fi;
				ny=next.sec;
				
				if(isvalid(nx,ny))
				{
					if(g[nx][ny]!='#' && a[nx][ny]==inf)
					{
						a[nx][ny]=a[x][y]+1;
						q.push(mp(nx,ny));
					}
				}
				
				
			}
			
			char c=g[x][y];
			
			if(islower(c))
			{
				for(auto next:tp[c-'a'])
				{
					ll nx,ny;
					nx=next.fi;
					ny=next.sec;
					
					if(a[nx][ny]==inf)
					{
						a[nx][ny]=a[x][y]+1;
						q.push(mp(nx,ny));
					}
				}
			
				tp[c-'a'].clear();
			
			}
		
			
			
		}
		
		ll ans=a[ex][ey];
		
		if(ans==inf)
		{
			cout<<-1<<Endl;
		}
		else
		{
			cout<<ans<<endl;
		}
		
																										
	
	return 0;
}

#include<bits/stdc++.h>
#define rep(i,n) for(int i = 0 ; i < (n); ++i)
using namespace std ;
typedef long long ll ;
const int mod=1000000007;
const int INF=1e5 ;

pair<int,int> dir[4]={{0,1},{1,0},{-1,0},{0,-1}};

void solve(){

	int h,w ;
	cin>>h>>w ;

	vector<string> s(h) ;

	rep(i,h){
		cin>>s[i] ;
	}

	queue<pair<int,int>> q ;

	vector<vector<pair<int,int>>> l(26) ;

	vector<vector<int>> dist(h,vector<int>(w,INF)) ; 

	pair<int,int> d ;
	
	rep(i,h)rep(j,w){
		if(s[i][j]=='S'){
		q.push({i,j}) ;
		dist[i][j]=0 ;
	}
	if(s[i][j]=='G'){
		d.first=i ;
		d.second=j ;
		}
	}

	rep(i,h)rep(j,w){
			if(islower(s[i][j]))
			l[s[i][j]-'a'].push_back({i,j}) ;
	}

	while(!q.empty()){

		int i=q.front().first ;
		int j=q.front().second ;

		q.pop() ;

		for(auto v:dir)
		{
			int ni=i+v.first ;
			int nj=j+v.second ;

			if(ni<0 || ni>=h || nj<0 || nj>=w) continue ;
			if(s[ni][nj]=='#') continue ;
			if(dist[ni][nj]!=INF)	continue ;
			dist[ni][nj]=dist[i][j]+1 ;
			q.push({ni,nj}) ;
		}
	
		if(islower(s[i][j])){
			
			for(auto p:l[s[i][j]-'a']){
				int ni=p.first ;
				int nj=p.second ;
				if(dist[ni][nj]!=INF) continue ;
				dist[ni][nj]=dist[i][j]+1 ;
				q.push({ni,nj}) ;

			}
		
		l[s[i][j]-'a']=vector<pair<int,int>>() ; 

		}
	}
	
	if(dist[d.first][d.second]==INF)
		cout<<-1 ;
	else
		cout<<dist[d.first][d.second]	;
}

int main(){
 
 

		int y ;

		y=1 ;
		//cin>>y ;

		while(y--){
 
			solve() ;
			
		}
	return 0 ;
}