#include <bits/stdc++.h>

namespace {
    using namespace std;
#define int long long

    template<typename T>
    inline bool whitespace(const vector<T> &) { return false; }

    template<typename T>
    inline bool whitespace(const T &) { return true; }

    inline bool whitespace(const char) { return false; }

    template<typename F, typename S>
    inline bool whitespace(const pair<F, S> &) { return false; }

    template<typename F, typename S>
    ostream &operator<<(ostream &os, const pair<F, S> &p) {
        os << p.first << (whitespace(p.second) ? " " : "") << p.second << "\n";
        return os;
    }

    template<typename F, typename S>
    istream &operator>>(istream &is, pair<F, S> &p) {
        is >> p.first >> p.second;
        return is;
    }

    template<typename T>
    istream &operator>>(istream &is, vector<T> &v) {
        for (T &t : v) is >> t;
        return is;
    }

    template<typename T>
    ostream &operator<<(ostream &os, const vector<T> &v) {
        for (const T &t : v) os << t << (whitespace(t) ? " " : "");
        os << "\n";
        return os;
    }

    template<typename T>
    istream &operator>>(istream &is, deque<T> &v) {
        for (T &t : v) is >> t;
        return is;
    }

    template<typename T>
    ostream &operator<<(ostream &os, const deque<T> &v) {
        for (const T &t : v) os << t << (whitespace(t) ? " " : "");
        os << "\n";
        return os;
    }

    class exit_exception : exception {
    };

    void answer() {}

    template<typename First, typename... Args>
    void answer(First &&val, Args &&... ans) {
        cout << val << "\n";
        answer(ans...);
        throw exit_exception();
    }

    struct autoint {
        int x;

        autoint(int i) : x(i) {}

        autoint() { cin >> x; }

        operator int() { return x; }

        int operator--() { return --x; }

        int operator--(signed) { return x--; }

        int operator++() { return ++x; }

        int operator++(signed) { return x++; }
    };
}

void solve();

signed main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int t = 1;
//    cin >> t;
    do { try { solve(); } catch (exit_exception &) {}} while (--t);
    return 0;
}


void solve() {
    autoint h, w;
    vector<vector<pair<int, int>>> graph(h * w + 26);
    vector<vector<char>> board(h, vector<char>(w));
    cin >> board;
    int start = 0, finish = 0;
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            if (board[i][j] == 'S') start = i * w + j;
            if (board[i][j] == 'G') finish = i * w + j;
            vector<int> dx{-1, 0, 1, 0};
            vector<int> dy{0, -1, 0, 1};
            for (int k = 0; k < 4; ++k) {
                int x = i + dx[k], y = j + dy[k];
                if (x < 0 || x == h || y < 0 || y == w) continue;
                if (board[x][y] == '#' || board[i][j] == '#') continue;
                graph[i * w + j].emplace_back(x * w + y, 2);
                graph[x * w + y].emplace_back(i * w + j, 2);
            }
            if ('a' <= (board[i][j]) && board[i][j] <= 'z') graph[i * w + j].emplace_back(h * w + board[i][j] - 'a', 1);
            if ('a' <= (board[i][j]) && board[i][j] <= 'z') graph[h * w + board[i][j] - 'a'].emplace_back(i * w + j, 1);
        }
    }
    queue<int> bfs;
    bfs.push(start);
    vector<int> dist(graph.size(), 1e9);
    dist[start] = 0;
    while (!bfs.empty()) {
        int cur = bfs.front();
        bfs.pop();
        for (auto next : graph[cur]) {
            if (dist[next.first] > dist[cur] + next.second) {
                dist[next.first] = dist[cur] + next.second;
                bfs.push(next.first);
            }
        }
    }
    cout << (dist[finish] == 1e9 ? -1 : dist[finish] / 2) << '\n';
}
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef pair<int, int> P;
const int INF = 5e6;

int di[4] = {1, 0, -1, 0};
int dj[4] = {0, 1, 0, -1};

int main() {
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  rep(i,h) cin >> s[i];
  // vector dist(h, vector(w, INF));
  vector<vector<int>> dist(h, vector<int>(w, INF));
  queue<P> q;
  rep(i,h)rep(j,w) {
    if (s[i][j] == 'S') {
      q.emplace(i,j);
      dist[i][j] = 0;
    }
  }
  vector<vector<P>> warps(256);
  rep(i,h)rep(j,w) warps[s[i][j]].emplace_back(i,j);
 
  while (!q.empty()) {
    auto [i,j] = q.front(); q.pop();
    if (s[i][j] == 'G') {
      cout << dist[i][j] << endl;
      return 0;
    }
    rep(v,4) {
      int ni = i + di[v], nj = j + dj[v];
      if (ni < 0 || ni >= h || nj < 0 || nj >= w) continue;
      if (s[ni][nj] == '#') continue;
      if (dist[ni][nj] != INF) continue;
      dist[ni][nj] = dist[i][j] + 1;
      q.emplace(ni,nj);
    }
 
    if (islower(s[i][j])) {
      for (P p : warps[s[i][j]]) {
        int ni = p.first, nj = p.second;
        if (dist[ni][nj] != INF) continue;
        dist[ni][nj] = dist[i][j] + 1;
        q.emplace(ni,nj);
      }
      warps[s[i][j]] = vector<P>();
    }
  }
  cout << -1 << endl;
  return 0;
}
