#define _CRT_SECURE_NO_WARNINGS

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include "stdio.h"

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<ll, pll> plll;
#define mp(x,y) make_pair(x,y)

// input

void read(ll a[], int s, int n) {
	for (int i = 0 + s; i < n + s; ++i) {
		scanf("%ll", &a[i]);
	}
}

void read(int a[], int s, int n) {
	for (int i = 0 + s; i < n + s; ++i) {
		scanf("%d", &a[i]);
	}
}

// fenwick

ll getSum(ll bits[], int index)
{
	ll sum = 0;
	while (index > 0)
	{
		sum += bits[index];
		index -= index & (-index);
	}
	return sum;
}

void updateAt(ll bits[], int n, int index, ll val)
{
	while (index <= n)
	{
		bits[index] += val;
		index += index & (-index);
	}
}

static const int MX_VAL = 1e6 + 2;
ll bits[MX_VAL + 1] = {};

// inversions

ll getInvCnt(ll a[], int n)
{
	ll cnt = 0;
	memset(bits, 0, sizeof(bits));
	for (int i = n - 1; i >= 0; i--)
	{
		cnt += getSum(bits, a[i] - 1);
		updateAt(bits, MX_VAL, a[i], 1);
	}

	return cnt;
}

// MODFIY N!!!
const int N = 1 * 1e6 + 2;

// MODFIY MOD!!!
const int MOD = 1e9 + 7;

long long fac[N], rfac[N];

long long mul(long long a, long long b) { return 1LL * a * b % MOD; }

long long fpow(long long a, long long b) {
	if (b == 0) return 1;
	long long re = fpow(a, b / 2);
	if (b % 2 == 1) return mul(a, mul(re, re));
	return mul(re, re);
}

long long inv(long long x) {
	return fpow(x, MOD - 2);
}

int nck(int x, int y) {
	return mul(fac[x], mul(rfac[y], rfac[x - y]));
}

void prepareFac()
{
	fac[0] = 1;
	rfac[0] = inv(1);
	for (int i = 1; i < N; ++i) {
		fac[i] = i * fac[i - 1] % MOD, rfac[i] = inv(fac[i]);
	}
}

ll gcd(ll a, ll b) {
	if (b == 0) return a;
	return gcd(b, a%b);
}
ll nok(ll a, ll b) {
	return a * b / gcd(a, b);
}


int a[N], b[N];
string s[2000];
vector<pii> v[256];
int vis[2000 * 2000];
int visa[256];
int ind(pii pii) {
	return pii.first * 2000 + pii.second;
}

int n, m, cost; queue<pii> q;
void go(int x, int y) {
	if (x < 0 || x == n)
		return;
	if (y < 0 || y == m)
		return;
	auto c = mp(x, y);
	if (vis[ind(c)])
		return;
	if (s[x][y] == '#')
		return;
	q.push(c);
	vis[ind(c)] = cost;
}

void solve_case()
{
	
	cin >> n >> m;
	pii start, finish;

	for (int i = 0; i < n; ++i) {
		cin >> s[i];
		for (int j = 0; j < s[i].length(); ++j)
			if (s[i][j] == 'S')
				start = mp(i, j);
			else if (s[i][j] == 'G')
				finish = mp(i, j);
			else if (s[i][j] >= 'a' && s[i][j] <= 'z')
				v[s[i][j]].push_back(mp(i, j));
	}

	
	q.push(start);
	vis[ind(start)] = 1;
	while (!q.empty()) {
		auto c = q.front(); q.pop();
		if (c == finish) {
			cout << vis[ind(c)] - 1;
			return;
		}
		cost = vis[ind(c)] + 1;
		go(c.first - 1, c.second);
		go(c.first + 1, c.second);
		go(c.first , c.second + 1);
		go(c.first, c.second - 1);
		int x = c.first;
		int y = c.second;
		if (s[x][y] >= 'a' && s[x][y] <= 'z' && !visa[s[x][y]]) {
			visa[s[x][y]] = true;
			for (auto p : v[s[x][y]]) {
				if (!vis[ind(p)]) {
					vis[ind(p)] = cost;
					q.push(p);
				}
			}
		}

	}
	cout << -1;
	cout << endl;
}

void prepare()
{
}


int main()
{
#ifdef __OLIMP__
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	int T = 1;
	// scanf("%d", &T);
	//prepare();
	for (int tc = 1; tc <= T; tc++)
		solve_case();

	return 0;
}
#include <bits/stdc++.h>
 
#define pb push_back
#define db1(x) cout << #x << " = " << x << endl
#define db2(x, y) cout << #x << " = " << x << ", " << #y << " = " << y << endl
#define paging cout << "-----------------------" << endl
 
using namespace std;
void localFileInput() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
}
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int dir[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1};
const ll mod = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 2010;
int n, m;
char s[N][N];
bool vis[N][N];
bool use[30];
int f[N][N];
vector<pii> v[30];
pii st;
bool check(int x, int y) {
    return (x>=0&&x<n) && (y>=0&&y<m) && !vis[x][y] && s[x][y] != '#';
}
int bfs() {
    int x = st.first;
    int y = st.second;
    vis[x][y] = true;
    f[x][y] = 0;
    queue<pii> que; que.push(st);
    while(!que.empty()) {
        pii p = que.front(); que.pop();
        x = p.first;
        y = p.second;
        if(s[x][y] == 'G') return f[x][y];
        if(islower(s[x][y])) {
            int t = s[x][y] - 'a';
            if(!use[t]) {
                use[t] = true;
                for (pii val : v[t]) if(!vis[val.first][val.second]) {
                    vis[val.first][val.second] = true;
                    f[val.first][val.second] = f[x][y] + 1;
                    que.push(val);
                }
            }
        }
        for (int i = 0; i < 4; ++ i) {
            int nx = x + dir[i][0];
            int ny = y + dir[i][1];
            if(check(nx, ny)) {
                vis[nx][ny] = true;
                f[nx][ny] = f[x][y] + 1;
                que.push({nx, ny});
            }
        }
    }
    return -1;
}
void sol() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; ++ i) scanf("%s", s[i]);
    for (int i = 0; i < n; ++ i) for (int j = 0; j < m; ++ j) {
        if(s[i][j] == 'S') st = {i, j};
        if(islower(s[i][j])) {
            v[s[i][j]-'a'].pb({i, j});
        }
    }
    printf("%d\n", bfs());
}
int main()
{
    localFileInput();
    // int _; scanf("%d", &_); while(_ --)
    sol();
    return 0;
}