#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2212"
#include<bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (n); i++)
#include"library/graph/Grid.hpp"
#include"library/sequence/AhoCorasick.hpp"conststd::map<char,int>mp{{'D',0},{'R',1},{'U',2},{'L',3}};intsolve(inth,intw){std::vector<std::string>s(h);REP(i,h)std::cin>>s[i];Grid<char>GR(s,'#');intS=GR.find('S'),T=GR.find('G');auto&G=GR.G;AhoCorasick<char,4>AC;intm;std::cin>>m;REP(_,m){std::stringt;std::cin>>t;std::vector<char>tt(t.size());REP(i,t.size())tt[i]=mp.at(t[i]);AC.add(tt);}AC.build();std::vectordp(h*w,std::vector<int>(AC.size(),-1));std::queue<std::pair<int,int>>que;que.emplace(S,0);dp[S][0]=0;while(que.size()){auto[idx,now]=que.front();que.pop();for(auto&e:G[idx]){intnxt=AC.nxt(now,e.weight);if(AC.val(nxt))continue;if(dp[e.to][nxt]<0){dp[e.to][nxt]=dp[idx][now]+1;que.emplace(e.to,nxt);}if(e.to==T)returndp[e.to][nxt];}}return-1;}intmain(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);inth,w;while(std::cin>>h>>w,h)std::cout<<solve(h,w)<<"\n";}
#line 1 "test/AOJ/2212.test.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2212"
#include<bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (n); i++)
#line 2 "library/graph/WeightedGraph.hpp"
template<typenameT>structWeightedEdge{WeightedEdge()=default;WeightedEdge(intfrom,intto,Tweight):from(from),to(to),weight(weight){}intfrom,to;Tweight;operatorint()const{returnto;}};template<typenameT>structWeightedGraph{intn;usingweight_type=T;usingedge_type=WeightedEdge<T>;std::vector<edge_type>edges;protected:std::vector<int>in_deg;boolprepared;classOutgoingEdges{WeightedGraph*g;intl,r;public:OutgoingEdges(WeightedGraph*g,intl,intr):g(g),l(l),r(r){}edge_type*begin(){return&(g->edges[l]);}edge_type*end(){return&(g->edges[r]);}edge_type&operator[](inti){returng->edges[l+i];}intsize()const{returnr-l;}};classConstOutgoingEdges{constWeightedGraph*g;intl,r;public:ConstOutgoingEdges(constWeightedGraph*g,intl,intr):g(g),l(l),r(r){}constedge_type*begin()const{return&(g->edges[l]);}constedge_type*end()const{return&(g->edges[r]);}constedge_type&operator[](inti)const{returng->edges[l+i];}intsize()const{returnr-l;}};public:OutgoingEdgesoperator[](intv){assert(prepared);return{this,in_deg[v],in_deg[v+1]};}constConstOutgoingEdgesoperator[](intv)const{assert(prepared);return{this,in_deg[v],in_deg[v+1]};}boolis_prepared()const{returnprepared;}WeightedGraph():n(0),in_deg(1,0),prepared(false){}WeightedGraph(intn):n(n),in_deg(n+1,0),prepared(false){}WeightedGraph(intn,intm,booldirected=false,intindexed=1):n(n),in_deg(n+1,0),prepared(false){scan(m,directed,indexed);}voidresize(intn){n=n;}voidadd_arc(intfrom,intto,Tweight){assert(!prepared);assert(0<=fromandfrom<nand0<=toandto<n);edges.emplace_back(from,to,weight);in_deg[from+1]++;}voidadd_edge(intu,intv,Tweight){add_arc(u,v,weight);add_arc(v,u,weight);}voidadd_arc(constedge_type&e){add_arc(e.from,e.to,e.weight);}voidadd_edge(constedge_type&e){add_edge(e.from,e.to,e.weight);}voidscan(intm,booldirected=false,intindexed=1){edges.reserve(directed?m:2*m);while(m--){intu,v;std::cin>>u>>v;u-=indexed;v-=indexed;Tweight;std::cin>>weight;if(directed)add_arc(u,v,weight);elseadd_edge(u,v,weight);}build();}voidbuild(){assert(!prepared);prepared=true;for(intv=0;v<n;v++)in_deg[v+1]+=in_deg[v];std::vector<edge_type>new_edges(in_deg.back());autocounter=in_deg;for(auto&&e:edges)new_edges[counter[e.from]++]=e;edges=new_edges;}voidgraph_debug()const{#ifndef __DEBUG
return;#endif
assert(prepared);for(intfrom=0;from<n;from++){std::cerr<<from<<";";for(inti=in_deg[from];i<in_deg[from+1];i++)std::cerr<<"("<<edges[i].to<<","<<edges[i].weight<<")";std::cerr<<"\n";}}};#line 3 "library/graph/Grid.hpp"
#define REP_(i, n) for (int i = 0; i < (n); i++)
template<typenameT>classGrid{constinth,w;std::optional<T>ban;// D,R,U,Lstaticconstexprstd::pair<int,int>d4[4]={{1,0},{0,1},{-1,0},{0,-1}};template<typenamevecvecT>voidbuild(constvecvecT&grid){REP_(y,h)REP_(x,w){intp=id(y,x);v[p]=grid[y][x];if(banandv[p]==ban.value())continue;REP_(d,4){inty2=y+d4[d].first,x2=x+d4[d].second;if(in(y2,x2)and(!banorban.value()!=grid[y2][x2]))G.add_arc(p,id(y2,x2),d);}}G.build();}public:std::vector<T>v;WeightedGraph<int>G;boolin(inty,intx)const{return0<=yandy<hand0<=xandx<w;}intid(inty,intx)const{assert(in(y,x));returny*w+x;}std::pair<int,int>r2(inta)const{assert(0<=aanda<h*w);return{a/w,a%w};}Grid(conststd::vector<std::vector<T>>&grid,conststd::optional<T>&ban=std::nullopt):h(grid.size()),w(grid[0].size()),ban(ban),v(h*w),G(h*w){build(grid);}Grid(conststd::vector<std::string>&s,conststd::optional<T>&ban=std::nullopt):h(s.size()),w(s[0].size()),ban(ban),v(h*w),G(h*w){static_assert(std::is_same<T,char>::value,"value_type==char");build(s);}intfind(constT&c)const{REP_(i,h*w)if(v[i]==c)returni;return-1;}};#undef REP_
#line 2 "library/algebra/group/Add.hpp"
template<typenameX>structGroupAdd{usingvalue_type=X;staticconstexprXop(constX&x,constX&y)noexcept{returnx+y;}staticconstexprvoidRchop(X&x,constX&y){x+=y;}staticconstexprvoidLchop(constX&x,X&y){y+=x;}staticconstexprXinverse(constX&x)noexcept{return-x;}staticconstexprXpower(constX&x,longlongn)noexcept{returnX(n)*x;}staticconstexprXunit(){returnX(0);}staticconstexprboolcommute=true;};#line 2 "library/sequence/ForString.hpp"
template<charMARGIN>structForString{staticconstexprcharchange(charc){returnc-MARGIN;}staticconstexprcharrestore(chara){returna+MARGIN;}staticstd::vector<char>change(conststd::string&s){std::vector<char>v(s.size());for(inti=0;i<s.size();i++)v[i]=change(s[i]);returnv;}staticstd::stringrestore(conststd::vector<char>&v){std::strings(v.size(),'#');for(inti=0;i<v.size();i++)s[i]=restore(v[i]);returns;}};structFSAa{staticconstexprcharchange(charc){returnc<='Z'?c-'A':26+c-'a';}staticconstexprcharrestore(chara){returna<26?'A':a-26+'a';}staticstd::vector<char>change(conststd::string&s){std::vector<char>v(s.size());for(inti=0;i<s.size();i++)v[i]=change(s[i]);returnv;}staticstd::stringrestore(conststd::vector<char>&v){std::strings(v.size(),'#');for(inti=0;i<v.size();i++)s[i]=restore(v[i]);returns;}};usingFSA=ForString<'A'>;usingFSa=ForString<'a'>;usingFS0=ForString<'0'>;#ifdef STR
#define STRA(s) \
STR(s##tomato); \
auto s = FSA::change(s##tomato);
#define STRa(s) \
STR(s##tomato); \
auto s = FSa::change(s##tomato);
#define STR0(s) \
STR(s##tomato); \
auto s = FS0::change(s##tomato);
#endif
#line 4 "library/sequence/Trie.hpp"
template<typenameCHAR,intSIGMA,typenameAbelMonoid=GroupAdd<int>>classTrie{protected:usingX=typenameAbelMonoid::value_type;structNode{std::array<int,SIGMA>nxt;intpre;Xval,suffix_val;// suffix_val は自身を含まないNode(intpre):pre(pre),val(AbelMonoid::unit()),suffix_val(AbelMonoid::unit()){std::ranges::fill(nxt,-1);}};std::vector<Node>nodes;public:Trie():nodes(1,Node(-1)){}int&nxt(intnow,constCHAR&a){returnnodes[now].nxt[a];}constint&nxt(intnow,constCHAR&a)const{returnnodes[now].nxt[a];}intadd(conststd::vector<CHAR>&v,Xx=1){intnow=0;for(constCHAR&a:v){assert(0<=aanda<SIGMA);if(!~nxt(now,a)){nxt(now,a)=nodes.size();nodes.emplace_back(now);}AbelMonoid::Rchop(nodes[now].suffix_val,x);now=nxt(now,a);}AbelMonoid::Rchop(nodes[now].val,x);returnnow;}intnode_idx(conststd::vector<CHAR>&v)const{// s の Node を返す 追加されて無ければ -1intnow=0;for(constCHAR&a:v){if(!~nxt(now,a))return-1;now=nxt(now,a);}returnnow;}Xval(conststd::vector<CHAR>&v){intid=node_idx(v);return(~id?nodes[id].val:AbelMonoid::unit());}X&val(intnode_id){returnnodes[node_id].val;}// vは含まないXprefix_prod(conststd::vector<CHAR>&v){intnow=0;Xsum=AbelMonoid::unit();for(constCHAR&a:v){if(!~nxt(now,a))break;AbelMonoid::Rchop(sum,nodes[now].val);now=nxt(now,a);}returnsum;}// vは含まないXsuffix_prod(conststd::vector<CHAR>&v)const{intid=node_idx(v);return(~id?nodes[id].suffix_val:AbelMonoid::unit());}std::vector<CHAR>restore(intnode_id){assert(0<=node_idandnode_id<nodes.size());std::vector<CHAR>res;while(~nodes[node_id].pre){intpre=nodes[node_id].pre;for(intj=0;j<SIGMA;j++)if(nxt(pre,j)==node_id){res.push_back(j);break;}node_id=pre;}std::ranges::reverse(res);returnres;}Xprod()const{returnnodes[0].suffix_val;}intsize()const{returnnodes.size();}template<typenameF>voidquery(conststd::vector<CHAR>&v,constF&f,intl=0,intr=-1){if(r<0)r=v.size();intnow=0;for(inti=l;i<r;i++){now=nxt(now,v[i]);if(~now)f(now);elsebreak;}}};#line 3 "library/sequence/AhoCorasick.hpp"
template<typenameCHAR,intSIGMA,typenameAbelMonoid=GroupAdd<int>>classAhoCorasick:Trie<CHAR,SIGMA,AbelMonoid>{usingsuper=Trie<CHAR,SIGMA,AbelMonoid>;usingsuper::nodes;usingX=typenameAbelMonoid::value_type;std::vector<int>suffix;boolprepared;public:usingsuper::nxt,super::add,super::node_idx,super::val,super::prefix_prod,super::suffix_prod,super::query,super::restore,super::prod,super::size;AhoCorasick():prepared(false){}boolis_prepared()const{returnprepared;}voidbuild(){assert(!prepared);prepared=true;suffix.resize(nodes.size());std::queue<int>que;que.push(0);while(que.size()){intnow=que.front();que.pop();for(inti=0;i<SIGMA;i++){int&nxt_id=nodes[now].nxt[i];if(~nxt_id){suffix[nxt_id]=(now?nodes[suffix[now]].nxt[i]:0);AbelMonoid::Rchop(val(nxt_id),val(suffix[nxt_id]));que.push(nxt_id);}elsenxt_id=(now?nodes[suffix[now]].nxt[i]:0);}}}Xpath_prod(conststd::vector<CHAR>&v){assert(prepared);Xres=AbelMonoid::unit();intnow=0;for(constCHAR&a:v){now=nxt(now,a);AbelMonoid::Rchop(res,val(now));}returnres;}};#line 7 "test/AOJ/2212.test.cpp"
conststd::map<char,int>mp{{'D',0},{'R',1},{'U',2},{'L',3}};intsolve(inth,intw){std::vector<std::string>s(h);REP(i,h)std::cin>>s[i];Grid<char>GR(s,'#');intS=GR.find('S'),T=GR.find('G');auto&G=GR.G;AhoCorasick<char,4>AC;intm;std::cin>>m;REP(_,m){std::stringt;std::cin>>t;std::vector<char>tt(t.size());REP(i,t.size())tt[i]=mp.at(t[i]);AC.add(tt);}AC.build();std::vectordp(h*w,std::vector<int>(AC.size(),-1));std::queue<std::pair<int,int>>que;que.emplace(S,0);dp[S][0]=0;while(que.size()){auto[idx,now]=que.front();que.pop();for(auto&e:G[idx]){intnxt=AC.nxt(now,e.weight);if(AC.val(nxt))continue;if(dp[e.to][nxt]<0){dp[e.to][nxt]=dp[idx][now]+1;que.emplace(e.to,nxt);}if(e.to==T)returndp[e.to][nxt];}}return-1;}intmain(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);inth,w;while(std::cin>>h>>w,h)std::cout<<solve(h,w)<<"\n";}