#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
 
//#define int long long
#define len(x) (int)x.length()
#define reset(x) memset(x,0,sizeof(x))
#define db1(x) cout<<#x<<"="<<x<<'\n'
#define db2(x,y) cout<<#x<<"="<<x<<","<<#y<<"="<<y<<'\n'
#define db3(x,y,z) cout<<#x<<"="<<x<<","<<#y<<"="<<y<<","<<#z<<"="<<z<<'\n'
#define rep(i,n) for(int i=0;i<(n);++i)
#define repA(i,a,n) for(int i=a;i<=(n);++i)
#define repD(i,a,n) for(int i=a;i>=(n);--i)
#define sz(a) (int)a.size()
#define pii pair<int,int>
#define all(a) a.begin(),a.end()
#define PI 3.1415926535897932384626433832795
#define INF 1000000000
#define MOD 1000000007
#define MOD2 1000000009
#define EPS 1e-6 
#define pb push_back
#define fi first
#define se second
#define mp make_pair
 
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};



signed main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	//freopen(".inp", "r", stdin);
    //freopen(".out", "w", stdout);
	string s;
	cin >> s;
	deque<char> dq;
	int dir = 0;
	for (int i = 0; i < s.length(); i++)
	{
		if (s[i] == 'R')
		{
			dir = 1 - dir;
			continue;
		}
		if (dir == 1)
		{
			dq.push_back(s[i]);
		} 
		else 
		{
			dq.push_front(s[i]);
		}
	}
	vector<char> final;
	while(dq.empty() == false)
	{
		final.pb(dq.back());
		dq.pop_back();
	}
	if (dir == 1)
	{
		reverse(all(final));
	}
	stack<char> sc;
	if (sz(final) == 0)
	{
	    cout <<"";
	    return 0;
	}
	/*for (auto x : final)
	{
	    cout << x;
	}*/
	sc.push(final[0]);
	for (int i = 1; i < sz(final); i++) 
	{
		if (sc.empty() == true) 
		{
			sc.push(final[i]);
		} 
		else 
		{
			if (sc.top() != final[i])
			{
			    sc.push(final[i]);
			}
			else 
			{
			    bool flag = false;
			    while(sc.empty() == false && i < sz(final) && sc.top() == final[i])
			    {
			        sc.pop(); i++; flag = true;
			    }
			    if (flag == true)
			    {
			        i--;
			    }
			}
		}
	}	
	stack<char> pp;
	while(!sc.empty())
	{
	    pp.push(sc.top());
	    sc.pop();
	}
	while(!pp.empty())
	{
	    cout << pp.top(); pp.pop();
	}
}

#include <iostream>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <string.h>
#include <vector>
#include <queue>
#include <cmath>
#include <complex>
#include <functional>
#include <numeric>
#include <iomanip>
#include <cassert>
#include <random>
#include <chrono>

/* #include <atcoder/all> */
/* using namespace atcoder; */
using namespace std;

void debug_out(){ cout << "\n"; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cout << H << " ";
  debug_out(T...);
}
#ifdef _DEBUG
#define debug(...) debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

#define SPBR(w, n) std::cout<<(w + 1 == n ? '\n' : ' ');
#define YES cout << "YES" << endl
#define Yes cout << "Yes" << endl
#define NO cout << "NO" << endl
#define No cout << "No" << endl
#define ALL(i) (i).begin(), (i).end()
#define FOR(i, a, n) for(int i=(a);i<(n);++i)
#define RFOR(i, a, n) for(int i=(n)-1;i>=(a);--i)
#define REP(i, n) for(int i=0;i<int(n);++i)
#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)
#define IN(a, x, b) (a<=x && x<b)
#define OUT(a, x, b) (x<a || b<=x)
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

using ll = long long;
using ull = unsigned long long;
using ld = long double;
const ll MOD = 1000000007;
/* const ll MOD = 998244353; */
const ll INF = (1<<30)-1;
const ll INFLL = 1ll<<60;
const double PI = acos(-1);

struct INIT { INIT(){
  cin.tie(0); ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
}}INIT;

int dx[] = {0, 1, 0, -1, 1, 1, -1, -1};
int dy[] = {1, 0, -1, 0, 1, -1, 1, -1};

struct T {
  int d, x, y;
  T(int d, int x, int y): d(d), x(x), y(y) {}

  bool operator < (const T &a) const {
    return d > a.d;
  }
};

signed main() {
  int H, W; 
  cin >> H >> W;

  vector<string> s(H);
  REP(i, H) cin >> s[i];

  int sx, sy, gx, gy;
  
  vector<vector<pair<int, int>>> v(26);

  REP(i, H) REP(j, W){
    if(s[i][j] == '.' || s[i][j] == '#') continue;
    if(s[i][j] == 'S'){
      sx = i; sy = j;
    }else if(s[i][j] == 'G'){
      gx = i; gy = j;
    }else{
      v[s[i][j]-'a'].emplace_back(i, j);
    }
  }

  priority_queue<T> q;
  q.emplace(0, sx, sy);

  vector<vector<int>> dist(H, vector<int>(W, INF));
  dist[sx][sy] = 0;


  while(!q.empty()){
    auto p = q.top(); q.pop();

    int d = p.d;
    int x = p.x;
    int y = p.y;

    if(dist[x][y] != d) continue;
    if(x == gx && y == gy) break;

    REP(i, 4){
      int nx = x+dx[i];
      int ny = y+dy[i];

      if(OUT(0, nx, H) || OUT(0, ny, W)) continue;
      if(s[nx][ny] == '#') continue;

      if(chmin(dist[nx][ny], dist[x][y]+1)){
        q.emplace(dist[nx][ny], nx, ny);
      }
    }

    vector<int> A, B;
    if('a' <= s[x][y] && s[x][y] <= 'z'){
      for(auto [nx, ny] : v[s[x][y]-'a']){
        if(chmin(dist[nx][ny], dist[x][y]+1)){
          q.emplace(dist[nx][ny], nx, ny);
          A.emplace_back(nx);
          B.emplace_back(ny);
        }
      }
    }

    if(A.size() > 0){
      REP(i, A.size()){
        s[A[i]][B[i]] = '.';
      }
      s[x][y] = '.';
    }
  }

  int ans = dist[gx][gy];
  if(ans == INF) ans = -1;

  cout << ans << "\n";

  return 0;
}
