#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
using namespace std;
typedef pair<int,int> pii;
int h,w,dis[4000500],sx,sy,tx,ty,vis[4000500];
char sp[2005][2005];
priority_queue<pii > q;
vector<int> gg[30];

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

int dp(int i,int j){return i*w+j;}

int main()
{
	scanf("%d%d",&h,&w);
	for(int i=0;i<h;i++)
		scanf("%s",sp[i]);
	for(int i=0;i<h;i++)
		for(int j=0;j<w;j++)
		{
			if(sp[i][j]=='S') sx=i,sy=j;
			if(sp[i][j]=='G') tx=i,ty=j;
			if(sp[i][j]>='a' && sp[i][j]<='z')
				gg[sp[i][j]-'a'].push_back(i*w+j);
		}
	memset(dis,-1,sizeof(dis));
	dis[sx*w+sy]=0;
	q.push(make_pair(0,sx*w+sy));
	while(!q.empty())
	{
		int now=q.top().second;q.pop();
		if(vis[now]) continue;vis[now]=1;
		if(now<h*w){
			int x=now/w,y=now%w;
			for(int a=0;a<4;a++)
			{
				int nx=x+dx[a],ny=y+dy[a];
				if(nx>=0 && nx<h && ny>=0 && ny<w && sp[nx][ny]!='#' && (dis[nx*w+ny]==-1 || dis[nx*w+ny]>dis[now]+1))
				{
					dis[nx*w+ny]=dis[now]+1;
					q.push(make_pair(-dis[nx*w+ny],nx*w+ny));
				}
			}
			if(sp[x][y]>='a' && sp[x][y]<='z')
			{
				int c=sp[x][y]-'a';
				if(dis[c+h*w]==-1 || dis[c+h*w]>dis[now])
				{
					dis[c+h*w]=dis[now];
					q.push(make_pair(-dis[c+h*w],c+h*w));
				}
			}
		} else {
			int c=now-h*w;
			for(int i=0;i<gg[c].size();i++)
			{
				if(dis[gg[c][i]]==-1 || dis[gg[c][i]]>dis[now]+1)
				{
					dis[gg[c][i]]=dis[now]+1;
					q.push(make_pair(-dis[gg[c][i]],gg[c][i]));
				}
			}
		}
	}
	// cout<<dis[dp(0,1)]<<" "<<dis[]
	printf("%d\n",dis[tx*w+ty]);
	return 0;
}
#include <stdio.h>
#include <stdlib.h>

#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <stdint.h>
#include <string.h>

#define _USE_MATH_DEFINES
#include <math.h>

#include <vector>
#include <list>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <deque>
#include <string>

#include <algorithm>
#include <functional>
#include <bitset>
#include <functional>
#include <chrono>
#include <random>

#define sqr(x) (x) * (x)

typedef unsigned int u32;
typedef int i32;
typedef unsigned long long int u64;
typedef long long int i64;
typedef uint16_t u16;
typedef int i16;
typedef uint8_t u8;
typedef int8_t i8;

using namespace std;
using namespace std::chrono;

const i64 mod = 1'000'000'000ll + 7;
//const i64 mod = 998'244'353ll;

const i64 inf = 1'000'000'000'000'000'000ll;

const long double eps = 1e-8;

i64 h, w;

i64 ind(pair<i64, i64> p) {
    return p.first * w + p.second;
}

int main(int argc, char* argv[]) {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cout.precision(15); cout.setf(ios::fixed); cerr.precision(15); cerr.setf(ios::fixed);

    if (sizeof(i64) != sizeof(long long int)) {
        cerr << "i64 != long long int" << endl;
    }

    cin >> h >> w;

    vector<string> a(h);
    for (i64 i = 0; i < h; i++) {
        cin >> a[i];
    }


    vector<vector<pair<i64, i64>>> z(256);
    for (i64 i = 0; i < h; i++) {
        for (i64 j = 0; j < w; j++) {
            char c = a[i][j];
            z[c].push_back({ i, j });
        }
    }
    z['.'].clear();

    auto s = z['S'].front();
    auto f = z['G'].front();

    vector<pair<i64, i64>> q;
    vector<i64> v(h * w);
    vector<i64> len;


    q.push_back(s);
    v[ind(s)] = 1;

    len.push_back(q.size());

    for (i64 i = 0; i < q.size(); i++) {
        if (len.back() == i) {
            len.push_back(q.size());
        }

        auto c = q[i];
        if (c == f) {
            cout << len.size() - 1 << endl;
            return 0;
        }


        for (auto x : {c.first - 1, c.first + 1}) {
            auto y = c.second;
            if (x < 0 || x >= h) {
                continue;
            }
            if (y < 0 || y >= w) {
                continue;
            }
            if (a[x][y] == '#') {
                continue;
            }

            pair<i64, i64> nxt = { x, y };
            if (v[ind(nxt)]) {
                continue;
            }
            v[ind(nxt)] = 1;
            q.push_back(nxt);
        }

        for (auto y : { c.second - 1, c.second + 1 }) {
            auto x = c.first;
            if (x < 0 || x >= h) {
                continue;
            }
            if (y < 0 || y >= w) {
                continue;
            }
            if (a[x][y] == '#') {
                continue;
            }

            pair<i64, i64> nxt = { x, y };
            if (v[ind(nxt)]) {
                continue;
            }
            v[ind(nxt)] = 1;
            q.push_back(nxt);
        }

        char w = a[c.first][c.second];
        for (auto nxt : z[w]) {
            if (v[ind(nxt)]) {
                continue;
            }
            v[ind(nxt)] = 1;
            q.push_back(nxt);
        }
        z[w].clear();
    }

    cout << -1 << endl;


    return 0;
}