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

typedef long long ll;
typedef unsigned long long ull;
const double pi = acos(-1);
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ull base = 131;
const ull mod1 = 1e9 + 9;
const ull mod2 = 1610612741;

const int maxn = 2e3 + 10;
int h, w;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
char p[maxn][maxn];
bool vis[maxn][maxn];
vector<pair<int, int> > v[30];
struct node
{
    int x, y, step;
    node(int a, int b, int c):x(a), y(b), step(c) {}
};
bool vis1[30];

int main()
{
    scanf("%d%d", &h, &w);
    for (int i = 1; i <= h; ++i) scanf("%s", p[i]+1);
    int x, y, s, t;
    for (int i = 1; i <= h; ++i)
        for (int j = 1; j <= w; ++j)
            if (p[i][j] == 'S') x = i, y = j;
            else if (p[i][j] >= 'a' && p[i][j] <= 'z') v[p[i][j]-'a'].push_back(make_pair(i, j));
            else if (p[i][j] == 'G') s = i, t = j;
    queue<node> q;
    q.push(node(x, y, 0));
    vis[x][y] = 1;
    while (!q.empty())
    {
        int x = q.front().x;
        int y = q.front().y;
        int step = q.front().step;
        q.pop();
//        if (vis[x][y]) continue;
//        vis[x][y] = 1;
        if (x == s && y == t) { printf("%d\n", step); return 0; }
        for (int i = 0; i < 4; ++i)
        {
            int nx = x+dx[i];
            int ny = y+dy[i];
            if (nx < 1 || nx > h) continue;
            if (ny < 1 || ny > w) continue;
            if (!vis[nx][ny] && p[nx][ny] != '#') q.push(node(nx, ny, step+1)), vis[nx][ny] = 1;
        }
        if (p[x][y] >= 'a' && p[x][y] <= 'z')
        {
            if (vis1[p[x][y]-'a']) continue;
            vis1[p[x][y]-'a'] = 1;
            for (int i = 0; i < v[p[x][y]-'a'].size(); ++i)
            {
                int nx = v[p[x][y]-'a'][i].first;
                int ny = v[p[x][y]-'a'][i].second;
                if (!vis[nx][ny]) q.push(node(nx, ny, step+1)), vis[nx][ny] = 1;
            }
        }
    }
    printf("-1\n");
    return 0;
}
#include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for(int i=0; i<(n); ++i)
#define RREP(i, n) for(int i=(n);i>=0;--i)
#define FOR(i, a, n) for (int i=(a); i<(n); ++i)
#define RFOR(i, a, b) for(int i=(a);i>=(b);--i)


#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(),(x).end()

#define DUMP(x) cerr<<#x<<" = "<<(x)<<endl
#define DEBUG(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl;

template<class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  REP(i, SZ(v)) {
    if (i) os << " ";
    os << v[i];
  }
  return os;
}

template <class T>
void debug(const vector<T> &v) {
  cout << "[";
  REP(i, SZ(v)) {
    if(i) cout << ", ";
    cout << v[i];
  }
  cout << "]" << endl;
}

template<class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << " " << p.second;
}

template <class T, class U>
void debug(const pair<T, U> &p) {
  cout << "(" << p.first << " " << p.second << ")" << endl;
}

template<class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template<class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;
using vvi = vector<vi>;
using vvll = vector<vll>;

const ll MOD = 1e9 + 7;
const int INF = INT_MAX;
const ll LINF = LLONG_MAX;
const int inf = INT_MIN;
const ll linf = LLONG_MIN;
const ld eps = 1e-9;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  int h, w; cin >> h >> w;

  vector<string> s(h);
  P st, gl;
  REP(i, h) {
    cin >> s[i];
    REP(j, w) {
      if(s[i][j] == 'S') st = {i, j};
      if(s[i][j] == 'G') gl = {i, j};
    }
  }

  vector<vector<P>> g(h*w+26);
  int dr[4] = {-1, 1, 0, 0};
  int dc[4] = {0, 0, -1, 1};
  REP(i, h) {
    REP(j, w) {
      REP(k, 4) {
        int nr = i + dr[k], nc = j + dc[k];
        if(!(0 <= nr && nr < h && 0 <= nc && nc < w) || s[nr][nc] == '#') {
          continue;
        }
        g[i*w+j].emplace_back(nr*w+nc, 2);
      }
    }
  }

  REP(i, h) {
    REP(j, w) {
      if('a' <= s[i][j] && s[i][j] <= 'z') {
        int tel = h * w + s[i][j] - 'a';
        g[i*w+j].emplace_back(tel, 1);
        g[tel].emplace_back(i*w+j, 1);
      }
    }
  }

  vi d(h*w+26, INF);
  d[st.first*w+st.second] = 0;
  priority_queue<P, vector<P>, greater<P>> pq;
  pq.push({0, st.first*w+st.second});

  while(!pq.empty()) {
    auto [nowd, now] = pq.top(); pq.pop();
    if(d[now] < nowd) continue;

    for(auto &[to, cost]: g[now]) {
      if(d[to] > nowd + cost) {
        d[to] = nowd + cost;
        pq.push({d[to], to});
      }
    }
  }

  int val = d[gl.first*w + gl.second];

  if(val == INF) {
    cout << -1 << endl;
  } else {
    cout << val/2 << endl;
  }



  return 0;
}
























































































