#include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)

using namespace std;

int NODE_NUM;

struct Node{
    map<char, Node*> next;
    Node* fail;
    vector<int> match;

    int node_id;
    Node() : fail(NULL) {
        node_id = NODE_NUM++;
    }
    ~Node(){ for(auto p : next) if(p.second) delete p.second; }
};

Node *build(vector<string> pattens){
    // 1. trie木 をつくる
    Node* root = new Node();
    root->fail = root;
    for(int i = 0; i < pattens.size(); i++){
        Node* p = root;
        for(auto c : pattens[i]){
            if(p->next[c] == 0) p->next[c] = new Node();
            p = p->next[c];
        }
        p->match.push_back(i);
    }

    // 2. failure link を作る
    queue<Node*> que;
    for(int i = 0; i < 128; i++){
        if(!root->next[i]){
            root->next[i] = root;
        }else{
            root->next[i]->fail = root;
            que.push(root->next[i]);
        }

    }
    while(!que.empty()){
        Node* p = que.front(); que.pop();
        for(int i = 0; i < 128; i++) if(p->next[i]) {
            Node* np = p->next[i];

            // add que
            que.push(np);

            // search failure link
            Node* f = p->fail;
            while(!f->next[i]) f = f->fail;
            np->fail = f->next[i];

            // update matching list
            np->match.insert(np->match.end(), np->fail->match.begin(), np->fail->match.end());
        }
    }
    return root;
}

 Node* next_node(Node* p, char c) {
     while(!p->next[c]) p = p->fail;
     return p->next[c];
 }

// クエリにマッチしたパターンについて 
// (last index, pattern id)のリストを返す
typedef pair<int, int> P;
vector<P> match(Node* root, string query){
    int n = query.size();
    vector<P> res;

    Node* p = root;
    REP(i, n) {
        int c = query[i];
        p = next_node(p, c);
        for(int k : p->match){
            res.push_back(P(i, k));
        }
    }

    return res;
}

struct State{
    int x, y;
    Node* p;
};

int main(){
    const int dx[4] = {1, 0, -1, 0};
    const int dy[4] = {0, 1, 0, -1};
    const char dc[4]= {'R', 'D', 'L', 'U'};

    int H, W;
    while(cin >> H >> W && H > 0) {
        vector<string> grid(H);
        REP(y, H) cin >> grid[y];

        int sx, sy, gx, gy;
        REP(y, H) REP(x, W) if(grid[y][x] == 'S') sx = x, sy = y, grid[y][x] = '.';
        REP(y, H) REP(x, W) if(grid[y][x] == 'G') gx = x, gy = y, grid[y][x] = '.';

        int PN;
        cin >> PN;
        vector<string> pat(PN);
        REP(i, PN) cin >> pat[i];

        NODE_NUM = 0;
        Node* root = build(pat);

        assert(NODE_NUM <= 110);
        int dist[50][50][110] = {};
        REP(y, H) REP(x, W) REP(i, NODE_NUM) dist[y][x][i] = INT_MAX;

        queue<State> que;
        que.push({sx, sy, root});
        dist[sy][sx][root->node_id] = 0;
        while(!que.empty()) {
            State s = que.front(); que.pop();
            int d = dist[s.y][s.x][s.p->node_id];
            REP(r, 4) {
                int nx = s.x + dx[r];
                int ny = s.y + dy[r];
                if(0 <= nx && 0 <= ny && nx < W && ny < H) {
                    if(grid[ny][nx] == '#') continue;
                    Node* np = next_node(s.p, dc[r]);
                    if(np->match.size() > 0) continue;
                    if(dist[ny][nx][np->node_id] > d + 1) {
                        dist[ny][nx][np->node_id] = d + 1;
                        que.push({nx, ny, np});
                    }
                }
            }
        }

        int ans = INT_MAX;
        REP(i, NODE_NUM) ans = min(ans, dist[gy][gx][i]);

        if(ans == INT_MAX) ans = -1;

        cout << ans << endl;

    }
    return 0;
}