#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <queue>
#include <map>
#include <fstream>
using namespace std;


class Sit{
public:
	int x,y;
	int cur;
};

/*
 * RXgN^É«¶ñðnµÄtry treeðì¬
 * »ÌãÍeíTõÖðÄÑoµÄAØÉÎµÄTõð©¯é±ÆªÅ«é
 */
class AhoCorasick{
private:
	static const int MAX_V=10001;
private:
	map<string,int> _dict;
	string idToStr[MAX_V];
	int _vertex;
	// »ÝÌ¶ñ©çÍÇÌ¶ñÖJÚÅ«é©
	map<int,set<int> > _stepPrv;
	// Tõ¸sµ½êÉßém[h
	map<int,int> _stepBack;
	// «¶ñÌW
	set<int> _dictStr;
	// _ÉîñðtÁµ½¢ÌÝgp
	//T _vertexInfos[MAX_V];
public:
	//AhoCorasick();
	AhoCorasick(const vector<string> inStrings):_vertex(1){
		for(int i=0;i<inStrings.size();i++){
			if(_dict.find(inStrings[i])==_dict.end()){
				idToStr[_vertex]=inStrings[i];
				_dict[inStrings[i]]=_vertex++;
				_dictStr.insert(_vertex-1);
			}
		}
		makeTree(inStrings);
	}
	int getStrId(string s){
		if(_dict.find(s)==_dict.end())return -1;
		return _dict[s];
	}
	int getVetex(){
		return _vertex;
	}
	// »ÝÌ¶ñðO©ç^¦AP¶¸ÂTõ
	bool isMatchOneByOne(char ch,int &cur){
		// KvÅ êÎA±±ÅcurªdictàÉ¶ÝµÈ¢©`FbN
		/*
		*/
		while(1){
			int nxt=cur;
			string nstr=idToStr[nxt];
			nstr+=ch;
			nxt=_dict[nstr];
			// àµ¡Ìê©çÌêÖJÚÂ\ÈçÎ
			if(_stepPrv.find(cur)!=_stepPrv.end()&&_stepPrv[cur].find(nxt)!=_stepPrv[cur].end()){
				// ¡ñÌê©çßêéêÅA}b`·éàÌª é©ð`FbN
				int tmpStr=nxt;
				while(tmpStr!=0){
					if(_dictStr.find(tmpStr)!=_dictStr.end())return true;
					tmpStr=_stepBack[tmpStr];
				}
				cur=nxt;
				break;
			}
			// »¤ÅÈ¯êÎAßÁÄÌ[vÅÄÑTõðs¤
			else{
				// rootÅ©Â©çÈ¯êÎAI¹
				if(cur==0)return false;
				// »ÝTõÌ¶ñÍm[hÉ¶ÝµÈ¢
				else if(_stepBack.find(cur)==_stepBack.end())cur=0;
				else{
					// rootÅÈ¢êÍAßÁÄ¡ñÌ¶ðà¤êx©é
					cur=_stepBack[cur];
				}
			}
		}
		// àµ«àÌ¶ñª©Â©êÎtrue
		if(_dictStr.find(cur)!=_dictStr.end())return true;
		return false;
	}

	// ­È­ÆàêÓ}b`µ½çtrue
	bool isMatchLeastOne(const string &s){
		int cur=0;
		for(int i=0;i<(int)s.size();i++){
			string cstr=idToStr[cur];
			string nstr=cstr+s[i];
			//
			int nxt=_dict[nstr];
			// àµ¡Ìê©çÌêÖJÚÂ\ÈçÎ
			if(_stepPrv.find(cur)!=_stepPrv.end()&&_stepPrv[cur].find(nxt)!=_stepPrv[cur].end()){
				cur=nxt;
				int tmpStr=nxt;
				// ßÁÄTõ
				while(tmpStr!=0){
					if(_dictStr.find(tmpStr)!=_dictStr.end())return true;
					tmpStr=_stepBack[tmpStr];
				}
			}
			// »¤ÅÈ¯êÎAßÁÄÌ[vÅÄÑTõðs¤
			else{
				// rootÅ©Â©çÈ¯êÎA¡ñÌ¶ÍòÎ·
				if(cur==0)continue;
				else if(_stepBack.find(cur)==_stepBack.end())cur=0;
				else{
					// rootÅÈ¢êÍAßÁÄ¡ñÌ¶ðà¤êx©é
					i--;
					cur=_stepBack[cur];
				}
			}
			// àµ«àÌ¶ñª©Â©êÎtrue
			if(_dictStr.find(cur)!=_dictStr.end())return true;
		}
		return false;
	}
private:
	// Rs[RXgN^ÆAãüZqÍgpÖ~É·é
	AhoCorasick(const AhoCorasick&ah);
	AhoCorasick &operator=(const AhoCorasick&ah);
private:
	// O(size(_dict)^2+size(_dict)*avg(strSize))
	void makeTree(const vector<string> &inStrings){
		// 0Ü½Íó¶ñª[gm[h
		_dict[""]=0;
		idToStr[0]="";
		for(int i=0;i<(int)inStrings.size();i++){
			for(int j=0;j<(int)inStrings[i].size();j++){
				string s=inStrings[i].substr(0,j+1);
				// Ü¾ÇÁ³êÄ¢È¢ÌÅ êÎAÇÁ·é
				if(_dict.find(s)==_dict.end()){
					idToStr[_vertex]=s;
					_dict[s]=_vertex++;
				}
			}
		}
		// TõðOÉißéûüÖGbWðÔ
		for(map<string,int>::iterator it=_dict.begin();it!=_dict.end();it++){
			for(map<string,int>::iterator iit=_dict.begin();iit!=_dict.end();iit++){
				if(it==iit)continue;
				// àµiit->firstªsize(it->first)+1¶Å\¬³êéÈçÎAGbWðø­
				if(it->first.size()==iit->first.size()-1
						&&it->first==iit->first.substr(0,it->first.size())){
					_stepPrv[it->second].insert(iit->second);
				}
			}
		}
		// TõðãëÖißéûüÖGbWðÔ
		for(map<string,int>::iterator it=_dict.begin();it!=_dict.end();it++){
			if(it->first=="")continue;
			// »ÝÌ¶ñ©çæªi¶ðæè¢½àÌÖßêé©ÔÉ`FbN
			// ßêÈ¯êÎ[gÖßé
			bool ok=false;
			for(int i=0;i<(int)it->first.size()-1;i++){
				string s=it->first.substr(i+1);
				if(_dict.find(s)!=_dict.end()){
					_stepBack[it->second]=_dict[s];
					ok=true;
					break;
				}
			}
			// [gÖßé
			if(!ok)_stepBack[it->second]=0;
		}
	}
};

int h,w;
int n;
char field[51][51];
string prohibits[20];
int sy,sx,gx,gy;
set<int> used[51][51];

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

int bfs(){
	vector<string> vs;
	for(int i=0;i<n;i++)vs.push_back(prohibits[i]);
	AhoCorasick ac(vs);
	Sit init;
	init.x=sx;
	init.y=sy;
	init.cur=0;
	queue<Sit> q[2];
	int cur=0;
	int nxt=1;
	q[cur].push(init);
	used[init.y][init.x].insert(0);
	int cnt=0;
	while(q[cur].size()){
		while(q[cur].size()){
			Sit s=q[cur].front();
			q[cur].pop();
			if(s.y==gy&&s.x==gx)return cnt;
			for(int i=0;i<4;i++){
				int ny=s.y+dy[i];
				int nx=s.x+dx[i];
				if(ny>=0&&nx>=0&&ny<h&&nx<w&&field[ny][nx]=='.'){
					char ch=i+'0';
					Sit nsit;
					nsit.y=ny;nsit.x=nx;
					nsit.cur=s.cur;
					bool b=ac.isMatchOneByOne(ch,nsit.cur);
					// matchµ½çAJÚµÈ¢
					if(b)continue;
					// nsit.curÌm[hÖ·ÅÉBµ½©Ç¤©
					if(used[ny][nx].find(nsit.cur)==used[ny][nx].end()){
						q[nxt].push(nsit);
						used[ny][nx].insert(nsit.cur);
					}
				}
			}
		}
		cnt++;
		swap(cur,nxt);
	}
	return -1;
}

int main(){

	while(cin>>h>>w&&(h|w)){
		for(int i=0;i<h;i++)for(int j=0;j<w;j++)used[i][j].clear();
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				cin>>field[i][j];
				if(field[i][j]=='S'){
					sy=i;
					sx=j;
					field[i][j]='.';
				}
				else if(field[i][j]=='G'){
					gy=i;
					gx=j;
					field[i][j]='.';
				}
			}
		}
		cin>>n;
		for(int i=0;i<n;i++){
			cin>>prohibits[i];
			for(int j=0;j<(int)prohibits[i].size();j++){
				if(prohibits[i][j]=='U')prohibits[i][j]='0';
				else if(prohibits[i][j]=='R')prohibits[i][j]='1';
				else if(prohibits[i][j]=='D')prohibits[i][j]='2';
				else if(prohibits[i][j]=='L')prohibits[i][j]='3';
			}
		}
		int res=bfs();
		cout<<res<<endl;
	}
	return 0;
}

Measured memory_bytes: 3400