#include <string>
#include <vector>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<stack>
#include<queue>
#include<cmath>
#include<algorithm>
#include<functional>
#include<list>
#include<deque>
#include<bitset>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<cstring>
#include<sstream>
#include<complex>
#include<iomanip>
#include<numeric>
#include<cassert>
#define X first
#define Y second
#define pb emplace_back
#define rep(X,Y) for (int (X) = 0;(X) < (Y);++(X))
#define reps(X,S,Y) for (int (X) = S;(X) < (Y);++(X))
#define rrep(X,Y) for (int (X) = (Y)-1;(X) >=0;--(X))
#define rreps(X,S,Y) for (int (X) = (Y)-1;(X) >= (S);--(X))
#define repe(X,Y) for ((X) = 0;(X) < (Y);++(X))
#define peat(X,Y) for (;(X) < (Y);++(X))
#define all(X) (X).begin(),(X).end()
#define rall(X) (X).rbegin(),(X).rend()
#define eb emplace_back
#define UNIQUE(X) (X).erase(unique(all(X)),(X).end())
#define Endl endl

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
template<class T> using vv=vector<vector<T>>;
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"{"; rep(i,t.size()) {os<<t[i]<<",";} os<<"}"<<endl; return os;}
template<class T,size_t n> ostream& operator<<(ostream &os, const array<T,n> &t) {
	os<<"{"; rep(i,n) {os<<t[i]<<",";} os<<"}"<<endl; return os;}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}
template<class S, class T,class U> ostream& operator<<(ostream &os, const tuple<S,T,U> &t) { return os<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<")";}
template<class S, class T,class U,class V> ostream& operator<<(ostream &os, const tuple<S,T,U,V> &t) { return os<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<","<<get<3>(t)<<")";}
template<class T> inline bool MX(T &l,const T &r){return l<r?l=r,1:0;}
template<class T> inline bool MN(T &l,const T &r){return l>r?l=r,1:0;}
//#undef NUIP
#ifdef NUIP
#define out(args...){vector<string> a_r_g_s=s_p_l_i_t(#args, ','); e_r_r(a_r_g_s.begin(), args); }
vector<string> s_p_l_i_t(const string &s, char c){vector<string> v;int d=0,f=0;string t;for(char c:s){if(!d&&c==',')v.pb(t),t="";else t+=c;if(c=='\"'||c=='\'')f^=1;if(!f&&c=='(')++d;if(!f&&c==')')--d;}v.pb(t);return move(v);}
void e_r_r(vector<string>::iterator it) {}
template<typename T, typename... Args> void e_r_r(vector<string>::iterator it, T a, Args... args){ if(*it==" 1"||*it=="1") cerr<<endl; else cerr << it -> substr((*it)[0] == ' ', it -> length()) << " = " << a << ", "; e_r_r(++it, args...);}
#else
#define out
#endif
#ifdef __cpp_init_captures
template<typename T>vector<T> table(int n, T v){ return vector<T>(n, v);}
template <class... Args> auto table(int n, Args... args){auto val = table(args...); return vector<decltype(val)>(n, move(val));}
#endif
const ll MOD=1e9+7;

const int NC = 255;

struct PMA {
  array<PMA*, NC+1> next; // next[0] is for fail
  vector<int> accept;
  PMA() : next() {}
};

PMA *buildPMA(vector<string> p) {
  auto root = new PMA;
  rep (i, p.size()) {
    auto t = root;
    for (char c : p[i]) {
      if (!t->next[c]) t->next[c] = new PMA;
      t = t->next[c];
    }
    t->accept.pb(i);
  }
  queue<PMA*> Q; // make failure link using bfs
  rep(c, NC+1) if (c) {
    if (root->next[c]) {
      root->next[c]->next[0] = root;
      Q.push(root->next[c]);
    } else root->next[c] = root;
  }
  while (!Q.empty()) {
    auto t = Q.front(); Q.pop();
    rep(c, NC+1) if (c) {
      if (t->next[c]) {
        Q.push(t->next[c]);
        auto r = t->next[0];
        while (!r->next[c]) r = r->next[0];
        t->next[c]->next[0] = r->next[c];
        copy(all(r->next[c]->accept), back_inserter(t->next[c]->accept));
      }
    }
  }
  return root;
}

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <tr1/unordered_set>
using namespace std;


#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=(x);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)

int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1}; //左 上 下 右
char d[4]={'L','U','R','D'};

bool match(PMA* &pma,const char s){
	int c=s;
	while(!pma->next[c]){
		pma=pma->next[0];
	}
	pma=pma->next[c];
	return !pma->accept.empty();
}

typedef pair<int,int> P;
P s,g;
int H,W;
char MAP[100][100];
struct State{
	int x,y;
	int turn;
	PMA* pma;
};
tr1::unordered_set<PMA*> ac[100][100];
int main(){
	for(;cin>>H>>W;){
		if((W|H)==0)break;
		for(int i=0;i<H;i++){
			string t;
			cin>>t;
			for(int j=0;j<W;j++){
				MAP[j][i]=t[j];
				if(MAP[j][i]=='S'){
					s=P(j,i);MAP[j][i]='.';
				}else if(MAP[j][i]=='G'){
					g=P(j,i);MAP[j][i]='.';
				}
				ac[j][i].clear();
			}
		}
		int n;
		cin>>n;
		vector<string> pat;
		REP(i,n){
      string s;
			cin>>s;
      pat.pb(s);
		}
		PMA *root=buildPMA(pat);
		queue<State> que;
		int ans=-1;
		que.push((State){s.first,s.second,0,root});
		while(!que.empty()){
			State t=que.front();
			que.pop();
			//移動
			if(t.x==g.first&&t.y==g.second){
				ans=t.turn;
				break;
			}
			PMA* next;
			REP(k,4){
				int nx=t.x+dx[k],ny=t.y+dy[k];
				if(nx>=0&&nx<W&&ny>=0&&ny<H&&MAP[nx][ny]=='.'){
					next=t.pma;
					if(match(next,d[k])==false){
						if(ac[nx][ny].find(next)!=ac[nx][ny].end())continue;
						que.push((State){nx,ny,t.turn+1,next});
						ac[nx][ny].insert(next);
					}
				}
			}
		}
		cout<<ans<<endl;
	}
}



Measured memory_bytes: 11972