#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;i++)
#define repn(i,n) for(int i=1;i<=n;i++)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define pb push_back
#define mpr make_pair

using namespace std;

const LL MOD=1e9+7;

int n,m,dist[2010][2010],dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
string s[2010];
deque <pair <int,pii> > q;
vector <pii> v[30];

bool out(int x,int y)
{
	return x<0||x>=n||y<0||y>=m;
}

int main()
{
	cin>>n>>m;
	rep(i,n) cin>>s[i];
	int sx,sy,tx,ty;
	rep(i,n)
	{
		rep(j,m)
		{
			if(s[i][j]=='S') sx=i,sy=j;
			if(s[i][j]=='G') tx=i,ty=j;
			if(islower(s[i][j])) v[s[i][j]-'a'].pb(mpr(i,j));
		}
	}
	rep(i,n+5) rep(j,2005) dist[i][j]=1e9;
	dist[sx][sy]=0;
	q.pb(mpr(0,mpr(sx,sy)));
	while(!q.empty())
	{
		pair <int,pii> f=q.front();
		q.pop_front();
		if(dist[f.se.fi][f.se.se]<f.fi) continue;
		if(f.se.fi==tx&&f.se.se==ty) break;//cout<<f.se.fi<<' '<<f.se.se<<endl;
		if(f.se.fi==n)
		{
			rep(i,v[f.se.se].size())
			{
				pii nxt=v[f.se.se][i];
				if(dist[nxt.fi][nxt.se]<=f.fi) continue;
				dist[nxt.fi][nxt.se]=f.fi;
				//cout<<nxt.se<<'p'<<endl;
				q.push_front(mpr(f.fi,mpr(nxt.fi,nxt.se)));
			}
			continue;
		}//cout<<f.se.fi<<' '<<f.se.se<<endl;
		rep(i,4)
		{
			int x=f.se.fi+dx[i],y=f.se.se+dy[i];
			if(out(x,y)||s[x][y]=='#'||dist[x][y]<=f.fi+1) continue;
			dist[x][y]=f.fi+1;
			q.pb(mpr(f.fi+1,mpr(x,y)));
		}
		if(islower(s[f.se.fi][f.se.se]))
		{
			if(dist[n][s[f.se.fi][f.se.se]-'a']>f.fi+1)
			{
				dist[n][s[f.se.fi][f.se.se]-'a']=f.fi+1;
				q.pb(mpr(f.fi+1,mpr(n,s[f.se.fi][f.se.se]-'a')));
			}
		}
		//cout<<f.se.fi<<' '<<f.se.se<<' '<<q.size()<<endl;
	}
	if(dist[tx][ty]==1e9) puts("-1");
	else cout<<dist[tx][ty]<<endl;
	return 0;
}
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int t;
    // cin >> t;
    t = 1;
    while (t--)
    {
        int n, m;
        cin >> n >> m;
        char arr[n + 1][m + 1];
        vector<vector<int>> vis(n + 1, vector<int>(m + 1, 0));
        unordered_map<char, vector<pair<int, int>>> map;
        int startx = 1, starty = 1;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                cin >> arr[i][j];
                if (arr[i][j] != '.' && arr[i][j] != '#')
                {
                    map[arr[i][j]].push_back({i, j});
                }
                if (arr[i][j] == 'S')
                {
                    startx = i;
                    starty = j;
                }
            }
        }
        int dr[] = {0, 0, 1, -1};
        int dc[] = {1, -1, 0, 0};
        queue<pair<int, int>> q;
        int level = 0;
        q.push({startx, starty});
        vis[startx][starty] = -1;
        bool flag = false;
        while (q.size() != 0)
        {
            int size = q.size();
            // cout << "size " << size << endl;
            for (int i = 0; i < size; i++)
            {
                pair<int, int> p = q.front();
                q.pop();
                int currx = p.first;
                int curry = p.second;
                char ch = arr[currx][curry];
                //  cout << currx << " " << curry << " " << ch << "level is " << level << endl;
                if (ch == 'G')
                {
                    flag = true;
                    break;
                }
                for (int j = 0; j < 4; j++)
                {
                    int x = currx + dr[j];
                    int y = curry + dc[j];
                    // cout << "inside dr dc " << x << " " << y << endl;
                    if (x > n || x < 1 || y < 1 || y > m || arr[x][y] == '#')
                        continue;
                    if (vis[x][y] != -1)
                    {
                        //   cout << "here" << endl;
                        vis[x][y] = -1;
                        q.push({x, y});
                    }
                }
                // cout << q.size() << endl;
                for (int j = 0; j < map[ch].size(); j++)
                {
                    // cout << "inside map " << endl;
                    int tempx = map[ch][j].first;
                    int tempy = map[ch][j].second;
                    if (vis[tempx][tempy] != -1)
                    {
                        vis[tempx][tempy] = -1;
                        q.push({tempx, tempy});
                    }
                }
                map.erase(ch);
                // cout << "end of map  " << endl;
            }
            //cout << "size heere is " << q.size() << endl;
            if (flag)
                break;
            level++;
        }
        if (flag)
        {
            cout << level << endl;
        }
        else
        {
            cout << -1 << endl;
        }
    }
    return 0;
}
