// Pratiyush Mishra

#include <bits/stdc++.h>
#define ull unsigned long long int
#define ll long long int
#define LL_MAX 9223372036854775807
#define pb push_back
#define pf push_front
#define mp make_pair
#define popb pop_back
#define vl vector<ll>
#define bs(v, x) binary_search(v.begin(), v.end(), x)
#define mem1(a) memset(a, -1, sizeof(a))
#define popf pop_front
#define p() cout << '\n'
#define p0(x) cout << x << " "
#define p1(x) cout << x << '\n'
#define p2(x, y) cout << x << " " << y << '\n'
#define p3(x, y, z) cout << x << " " << y << " " << z << '\n'
#define printv(v)                   \
  for (ll i = 0; i < v.size(); ++i) \
    cout << v[i] << " ";            \
  cout << '\n'
#define pr1(x) cout << fixed << setprecision(15) << x << '\n'
#define ordered_set tree<pair<ll, ll>, null_type, less<pair<ll, ll>>, rb_tree_tag, tree_order_statistics_node_update>
// ordered_set s ; s.order_of_key(val)  no. of elements strictly less than val
// s.find_by_order(i)  itertor to ith element (0 indexed)
#define mod 1000000007
#define mod1 998244353
#define fio                         \
  ios_base::sync_with_stdio(false); \
  cin.tie(NULL)
#define get(n) \
  ll n;        \
  cin >> n
#define getvec(v, n)         \
  vector<ll> v(n);           \
  for (ll i = 0; i < n; i++) \
    cin >> v[i];
#define getstr(s) \
  string s;       \
  cin >> s
#define all(x) x.begin(), x.end()
#define countBits(x) __builtin_popcount(x)
using namespace std;

//unordered_map < char, vector<pair<int, int>>> e;
vector<vector<pair<int, int>>> e(26);
vector<string> v;
int n, m, sx, sy, gx, gy;
vector<vector<int>> r = {{1, -1, 0, 0} , {0, 0, 1, -1}};
queue<pair<int, int>> q;
vector<int> visx(26);

void mainSolve()
{
  cin >> n >> m;
  for (int i = 0; i < n; i++)
  {
    getstr(s);
    v.pb(s);
    for (int j = 0; j < m; j++)
    {
      if (s[j] >= 'a' && s[j] <= 'z')
        e[s[j] - 'a'].pb({i, j});
      else if (s[j] == 'S')
      {
        sx = i;
        sy = j;
      }
      else if (s[j] == 'G')
      {
        gx = i;
        gy = j;
      }
    }
  }
  q.push({sx, sy});
  vector<vector<bool>> vis(n, vector<bool>(m, false));
  vis[sx][sy] = true;
  vector<vector<int>> dis(n, vector<int>(m, 0));
  while (!q.empty())
  {
    ll cx = q.front().first;
    ll cy = q.front().second;
    q.pop();
    if (v[cx][cy] >= 'a' && v[cx][cy] <= 'z' && !visx[v[cx][cy] - 'a'])
    {
      for (pair<int, int> it : e[v[cx][cy] - 'a'])
      {
        ll nx = it.first;
        ll ny = it.second;
        if (vis[nx][ny])
          continue;
        dis[nx][ny] = dis[cx][cy] + 1;
        vis[nx][ny] = true;
        q.push({nx, ny});
        //p2(nx, ny);
        if (nx == gx && ny == gy)
        {
          p1(dis[nx][ny]);
          return;
        }
      }
      visx[v[cx][cy] - 'a'] = true;
    }
    for (int j = 3; j >= 0; j--)
    {
      ll nx = cx + r[0][j];
      ll ny = cy + r[1][j];
      //p2(nx, ny);
      if (nx >= 0 && nx < n && ny >= 0 && ny < m && !vis[nx][ny] && v[nx][ny] != '#')
      {
        vis[nx][ny] = true;
        dis[nx][ny] = dis[cx][cy] + 1;
        q.push({nx, ny});
        //p2(nx, ny);
        if (nx == gx && ny == gy)
        {
          p1(dis[nx][ny]);
          return;
        }
      }
    }
  }
  p1(-1);
}

int main()
{
  fio;
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  //get(t);
  ll t = 1;
  while (t--)
  {
    mainSolve();
  }
  return 0;
}

/*        _____ __  __
  /^--^\  | () )\ \/ /
  \____/  |_()_) |__| 
 /      \ _____  _ __  __ ____  _     ____   ____  _____ 
|        || ()_)| |\ \/ /| ===|| |__ / (__` / () \|_   _|
 \__  __/ |_|   |_|/_/\_\|____||____|\____)/__/\__\ |_|  
|^|^\ \^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|^|
| | |\ \| | | | | | | | | | | | | | | | | | | | | | | | |
#####/ /#################################################
| | |\/ | | | | | | | | | | | | | | | | | | | | | | | | |
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|*/
#pragma GCC optimize("O4,unroll-loops,no-stack-protector")
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ull=unsigned long long;
using pii=pair<ll,ll>;
#define int ll

#define For(i,a,b)  for(int i=a;i<=b;i++)
#define Forr(i,a,b) for(int i=a;i>=b;i--)
#define F first
#define S second

#define eb emplace_back
#define all(x) x.begin(),x.end()
#define sz(x) ((int)x.size())
#define mkp make_pair

#define MOD (long long)(998244353)
#define INF (1e15)
#define EPS (1e-6)

#ifdef LOCALMEOW
#define debug(...) do{\
	cerr << __PRETTY_FUNCTION__ << " - " << __LINE__ <<\
	" : ("#__VA_ARGS__ << ") = ";\
	_OUT(__VA_ARGS__);\
}while(0)
template<typename T> void _OUT(T x) { cerr << x << "\n"; }
template<typename T,typename...I>
void _OUT(T x,I ...tail) { cerr << x << ", "; _OUT(tail...); }
#else
#define debug(...)
#endif
void INIT(){ ios::sync_with_stdio(false); cin.tie(0); }

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }
int lcm(int a,int b) { return a/gcd(a,b)*b; }
int fpow(int b,int p){
	int ans=1,now=b;
	while(p){
		if(p&1) ans=ans*now%MOD;
		p/=2; now=now*now%MOD;
	}
	return ans;
}

double dp[110][110][110];

double go(int a,int b,int c){
	if(dp[a][b][c]>=0) return dp[a][b][c];
	if(a>=100 || b>=100 || c>=100) return dp[a][b][c]=0;
	double ans=1;
	ans+=(double)a/(a+b+c)*go(a+1,b,c);
	ans+=(double)b/(a+b+c)*go(a,b+1,c);
	ans+=(double)c/(a+b+c)*go(a,b,c+1);
	return dp[a][b][c]=ans;
}

char g[2010][2010];
bool vis[2010][2010];

int32_t main(){
	INIT();
	//code...
	int n,m; cin>>n>>m;
	pii s,t;
	vector<vector<pii>> vtp(26);
	For(i,0,n+1) For(j,0,m+1){
		if(i==0 || j==0 || i==n+1 || j==m+1) g[i][j]='#';
		else cin>>g[i][j];
		if(g[i][j]=='S') s=mkp(i,j);
		else if(g[i][j]=='G') t=mkp(i,j);
		else if(g[i][j]>='a' && g[i][j]<='z') vtp[g[i][j]-'a'].eb(i,j);
	}
	memset(vis,0,sizeof(vis));
	queue<pair<pii,int>> que;
	que.emplace(s,0);
	vis[s.F][s.S]=1;
	while(!que.empty()){
		pii p=que.front().F;
		int d=que.front().S;
		que.pop();
		if(g[p.F][p.S]=='#') continue;
		if(p==t){
			cout<<d<<"\n";
			return 0;
		}
		if(g[p.F][p.S]>='a' && g[p.F][p.S]<='z'){
			for(auto &i:vtp[g[p.F][p.S]-'a']){
				if(!vis[i.F][i.S]){
					vis[i.F][i.S]=1;
					que.emplace(i,d+1);
				}
			}
		}
		if(!vis[p.F+1][p.S]){vis[p.F+1][p.S]=1;que.emplace(mkp(p.F+1,p.S),d+1);}
		if(!vis[p.F-1][p.S]){vis[p.F-1][p.S]=1;que.emplace(mkp(p.F-1,p.S),d+1);}
		if(!vis[p.F][p.S+1]){vis[p.F][p.S+1]=1;que.emplace(mkp(p.F,p.S+1),d+1);}
		if(!vis[p.F][p.S-1]){vis[p.F][p.S-1]=1;que.emplace(mkp(p.F,p.S-1),d+1);}
	}
	cout<<"-1\n";
	return 0;
}
