class _in{struct my_iterator{int it;const bool rev;explicit constexpr my_iterator(int it_, bool rev=false):it(it_),rev(rev){}constexpr int operator*(){return it;}constexpr bool operator!=(my_iterator& r){return it!=r.it;}void operator++(){rev?--it:++it;}};const my_iterator i,n;public:explicit constexpr _in(int n):i(0),n(n){}explicit constexpr _in(int i,int n):i(i,n<i),n(n){}constexpr const my_iterator& begin(){return i;}constexpr const my_iterator& end(){return n;}};

#include <bits/stdc++.h>
using namespace std;

template<int Code>
struct Node_ {
    Node_* next[Code];
    Node_* fail;
    bool is_taboo;
    Node_() : fail(nullptr), is_taboo(false)
      { fill_n(next, Code, nullptr);}
};

typedef Node_<4> node_t;

const int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
const string urdl = "URDL"; map<char, int> encoder;
void setEncoder() { for(int i : _in(4)) encoder[urdl[i]] = i;}

void constructAC(vector<node_t>& nodes, const vector<string>& patterns) {
    node_t* root = &nodes[0];
    //Phase 1 (trie)
    int count = 0;
    for(const auto& s : patterns) {
        node_t* cur = root;
        for(const char& c : s) {
            int k = encoder[c];
            if(cur->next[k] == nullptr)
              cur->next[k] = &nodes[++count];
            cur = cur->next[k];
        }
        cur->is_taboo = true;
    }

    //Phase 2 (failue link)
    queue<node_t*> que;
    for(int i : _in(4)) {
        if(root->next[i] != nullptr) {
            root->next[i]->fail = root;
            que.emplace(root->next[i]);
        }
        else
          root->next[i] = root;
    }
    
    while(!que.empty()) {
        node_t* cur = que.front(); que.pop();
        for(int i : _in(4)) {
            if(cur->next[i] == nullptr) continue;
            que.emplace(cur->next[i]);
            node_t* f = cur->fail;
            while(f->next[i] == nullptr) f = f->fail;
            cur->next[i]->fail = f->next[i];
        }
    }
}

bool getTaboo(node_t* cur, node_t* root) {
    if(cur == root) return false;
    if(cur->is_taboo == false)
      return getTaboo(cur->fail, root);
    else
      return true;
}
using bs = bitset<2500>;
int main() {
    cin.tie(0); ios::sync_with_stdio(false);
    setEncoder();
    int N, M;
    while(cin >> N >> M && N) {
        vector<string> fld(N);
        for(auto& s : fld) cin >> s;
        int P; cin >> P;
        vector<string> patterns(P);
        for(auto& s : patterns) cin >> s;
        vector<node_t> nodes(P * 10 + 1);
        constructAC(nodes, patterns);
        node_t* root = &nodes[0];
        int sx = -1, sy = -1;
        for(int i : _in(N))
          for(int j : _in(M))
            if(fld[i][j] == 'S'){
                sx = j, sy = i;
                break;
            }
        vector<bs> used(nodes.size());
        queue<tuple<int, int, int, int>> que;
        que.emplace(0, sx, sy, 0); used[0][sy * 50 + sx] = true;
        bool ok = false;
        while(!que.empty()) {
            int cid, cx, cy, dist;
            tie(cid, cx, cy, dist) = que.front(); que.pop();
            if(fld[cy][cx] == 'G') {
                cout << dist << endl;
                ok = true;
                break;
            }
            for(int i : _in(4)) {
                int nx = cx + dx[i], ny = cy + dy[i];
                if(nx < 0 || ny < 0 || M <= nx || N <= ny) continue;
                if(fld[ny][nx] == '#') continue;
                node_t* cur = &nodes[cid];
                while(cur->next[i] == nullptr) cur = cur->fail;
                cur = cur->next[i];
                if(getTaboo(cur, root)) continue;
                int id = cur - root;
                if(used[id][ny * 50 + nx] == true) continue;
                que.emplace(id, nx, ny, dist + 1);
                used[id][ny * 50 + nx] = true;
            }
        }
        if(!ok) cout << -1 << endl;
    }
}

Measured memory_bytes: 3184