#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <cstdio>
#include <cstring>
using namespace std;

#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)
#define DEB 0
#define all(x) x.begin(), x.end()
#define mp make_pair
#define pb push_back


class state{
public:
  int x,y;
  vector<int> ma; // 1base
  state(int _x, int _y, vector<int> m){
    x=_x; y=_y;
    ma.swap(m);
  }
  bool operator<(const state& a)const{
    if( x!=a.x ) return x<a.x;
    if( y!=a.y ) return y<a.y;
    return ma < a.ma;
  }
  bool operator==(const state& a)const{
    return x==a.x && y==a.y && ma==a.ma;
  }
};

const int dx[] = {0,1,0,-1}; //up, right, down, left
const int dy[] = {-1,0,1,0};
int n,m,p;
int sx,sy;
map<state,long long> msi;
char field[52][52];
vector<string> ope;

bool inside(int x, int y){
  return !(x<0 || x>=m || y>=n || y<0 || field[y][x]=='#');
}
int DIR(char c){
  if( c=='U' ) return 0;
  if( c=='R' ) return 1;
  if( c=='D' ) return 2;
  if( c=='L' ) return 3;
}
int main(){	
  while(cin>>n>>m,n|m){
    ope.clear();
    msi.clear();
    rep(i,n){
      cin>>field[i];
      rep(j,m)if( field[i][j]=='S' ){
	sx = j;
	sy = i;
      }
    }
    cin>>p;
    rep(i,p){
      string tmp; cin>>tmp;
      ope.pb(tmp);
    }
    // ª¶ñÅoÄ­éàÌÍí·é
    
    bool gao[16];
    memset(gao,true,sizeof(gao));
    rep(i,ope.size())if( gao[i] ){
      int j;
      for(j=0; j<ope.size(); j++)if( i!=j && gao[j] ){
	if( ope[i].find(ope[j]) != string::npos ){
	  gao[i] = false;
	  break;
	}
      }
    }
    vector<string> tmp;
    rep(i,ope.size())if( gao[i] )tmp.pb(ope[i]);
    ope.swap(tmp);

#if DEB
    puts("aaa");
    rep(i,ope.size()){
      cout << ope[i] << endl;
    }
#endif

    queue<state> q;
    bool goal = false;
    long long ans = -1;
    q.push(state(sx,sy,vector<int>(ope.size(),0)));
    msi[state(sx,sy,vector<int>(ope.size(),0))] = 0;
    while( !q.empty() ){
      int x = q.front().x;
      int y = q.front().y;
      vector<int> ma = q.front().ma;
      long long cost = msi[q.front()];
      q.pop();
#if DEB
      puts("init");
      printf("(%d,%lld),cost:%d\n",x,y,cost);
      rep(l,ma.size()){
	printf("%d,",ma[l]);
      }
      puts("");
#endif
      rep(k,4){
	vector<int> hoge(ope.size(),0);
	int tx = x + dx[k];
	int ty = y + dy[k];
	if( !inside(tx,ty) )continue;
	bool ok = true;
	rep(j,ma.size()){
	  if( DIR(ope[j][ma[j]+1-1]) == k ){
	    hoge[j] = ma[j]+1;
	    if( hoge[j]==ope[j].length() ){ ok = false; break; }
	  }else{
	    string aaa = ope[j].substr(0,ma[j]) + string(1,k==0?'U':k==1?'R':k==2?'D':'L');
	    int l;
	    for(l=0; l<aaa.size(); l++){
	      int u;
	      for(u=0; u+l<aaa.size(); u++){
		if( aaa[l+u]!=ope[j][u] )break;
	      }
	      if( u+l==aaa.size() ){
		break;
	      }
	    }
	    hoge[j] = aaa.size() - l;
	  }
	}
	if( !ok ) continue;

	if( field[ty][tx]=='G' ){
	  ans = cost + 1;
	  goal = true;
	}
	state ts(tx,ty,hoge);
	map<state,long long>::iterator it = msi.lower_bound(ts);
	if( it!=msi.end() && it->first==ts ){
	  if( it->second > cost+1 ){
	    it->second = cost+1;
	    q.push(ts);
#if DEB
	  puts("  update");
	  printf("  (%d,%d), dir:%d, cost:%lld\n",tx,ty,k,cost+1);
	  rep(l,hoge.size()){
	    printf("  %d",hoge[l]);
	  }
	  puts("");
#endif
	  }
	}else{
	  msi.insert(it,make_pair(ts,cost+1));
	  q.push(ts);
#if DEB
	  puts("  new");
	  printf("  (%d,%d), dir:%d, cost:%lld\n",tx,ty,k,cost+1);
	  rep(l,hoge.size()){
	    printf("  %d",hoge[l]);
	  }
	  puts("");
#endif
	}
      }
      if( goal ) break;
    }
    printf("%lld\n",ans);
  }
  return 0;
}

Measured memory_bytes: 9544