#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> ii;
typedef tuple<ll, ll, ll> iii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
#define REP(i,n) for (ll i = 0; i < (n); ++i)
#define REPR(i,n) for (ll i = (n)-1; i >= 0; --i)
#define FOR(i,m,n) for (ll i = (m); i < (n); ++i)
#define FORR(i,m,n) for (ll i = (n)-1; i >= (m); --i)
#define FORE(x,xs) for (const auto& x : (xs))
#define FORI(i,v) for (auto i = v.begin(); i != v.end(); i++)
#define ALL(v) v.begin(), v.end()
#define CHMIN(x,y) x = min(x, (y))
#define CHMAX(x,y) x = max(x, (y))
#define BIT(x,i) (((x) >> (i)) & 1)
#define YES(b) cout << ((b) ? "YES" : "NO") << endl
#define Yes(b) cout << ((b) ? "Yes" : "No") << endl

const int MAX = 2020;

int H, W;
string A[MAX];
int steps[MAX][MAX];

vii teles[30];
bool used[30];

int solve() {
    int gx = -1, gy = -1, sx = -1, sy = -1;
    REP (h, H) REP (w, W) {
        steps[h][w] = -1;
        if (A[h][w] == 'S') {
            sx = w, sy = h;
            steps[h][w] = 0;
        }
        if (A[h][w] == 'G') gx = w, gy = h;
        if ('a' <= A[h][w] && A[h][w] <= 'z') teles[A[h][w]-'a'].push_back(make_pair(w, h));
    }

    queue<ii> q;
    q.push(ii(sx, sy));
    while (!q.empty()) {
        int x, y; tie(x, y) = q.front();
        q.pop();
        int next = steps[y][x] + 1;

        if (x > 0 && steps[y][x-1] < 0 && A[y][x-1] != '#') {
            steps[y][x-1] = next;
            q.push(ii(x-1, y));
        }
        if (x < W-1 && steps[y][x+1] < 0 && A[y][x+1] != '#') {
            steps[y][x+1] = next;
            q.push(ii(x+1, y));
        }
        if (y > 0 && steps[y-1][x] < 0 && A[y-1][x] != '#') {
            steps[y-1][x] = next;
            q.push(ii(x, y-1));
        }
        if (y < H-1 && steps[y+1][x] < 0 && A[y+1][x] != '#') {
            steps[y+1][x] = next;
            q.push(ii(x, y+1));
        }

        if ('a' <= A[y][x] && A[y][x] <= 'z') {
            int k = A[y][x]-'a';
            if (!used[k]) {
                used[k] = 1;
                FORE (xy, teles[k]) {
                    int x_, y_; tie(x_, y_) = xy;
                    if ((x_ != x || y_ != y) && steps[y_][x_] < 0) {
                        steps[y_][x_] = next;
                        q.push(ii(x_, y_));
                    }
                }
            }
        }
    }

    return steps[gy][gx];
}

int main() {
    cout << fixed << setprecision(15);
    cin >> H >> W;
    REP (h, H) cin >> A[h];
    cout << solve() << endl;
}
#include <vector>
#include <queue>
#include <functional>
#include <utility>

using namespace std;

//  E[i]: vertexes which can be reased from i
//  W[i]: their weight
template<class T>
vector<T> dijkstra(vector<vector<int>> E, vector<vector<T>> W, int s, T inf)
{
    int n = (int)E.size();

    vector<T> D(n, inf);
    typedef pair<T,int> P;
    priority_queue<P,vector<P>,greater<P>> Q;

    D[s] = T();
    Q.push(make_pair(D[s], s));

    while (!Q.empty())
    {
        T d = Q.top().first;
        int p = Q.top().second;
        Q.pop();
        if (d > D[p])
            continue;
        for (int i=0; i<(int)E[p].size(); i++)
        {
            int t = E[p][i];
            if (d+W[p][i] < D[t])
                D[t] = d+W[p][i],
                Q.push(make_pair(D[t], t));
        }
    }
    return D;
}

#include <iostream>

int main()
{
    int H, W;
    cin>>H>>W;
    vector<string> a(H);
    for (string &t: a)
        cin>>t;

    vector<vector<int>> E(W*H+26), We(W*H+26);
    int S, G;
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, 1, -1};
    for (int y=0; y<H; y++)
    for (int x=0; x<W; x++)
        if (a[y][x]!='#')
        {
            if (a[y][x]=='S')
                S = y*W+x;
            if (a[y][x]=='G')
                G = y*W+x;

            for (int d=0; d<4; d++)
            {
                int tx = x+dx[d];
                int ty = y+dy[d];
                if (0<=tx && tx<W && 0<=ty && ty<H)
                {
                    E[y*W+x].push_back(ty*W+tx);
                    We[y*W+x].push_back(1);
                }
            }

            if ('a'<=a[y][x] && a[y][x]<='z')
            {
                E[y*W+x].push_back(W*H+a[y][x]-'a');
                We[y*W+x].push_back(1);
                E[W*H+a[y][x]-'a'].push_back(y*W+x);
                We[W*H+a[y][x]-'a'].push_back(0);
            }
        }

    int ans = dijkstra(E, We, S, W*H)[G];
    cout<<(ans<W*H ? ans : -1)<<endl;
}
