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

template <typename T>
std::vector<T> table(int n, T v) {
    return std::vector<T>(n, v);
}
 
template <typename... Args>
auto table(int n, Args... args) {
    auto val = table(args...);
    return std::vector<decltype(val)>(n, std::move(val));
}

struct alphabets { // example: lower letters
    static int const size = 4;
    static int convert(char c) {
        switch(c) {
        case 'R': return 0;
        case 'L': return 1;
        case 'U': return 2;
        case 'D': return 3;
        }
		assert(false); // unreachable
		return -1;
    }
    static char convert_inv(int i) {
		switch(i) {
		case 0: return 'R';
		case 1: return 'L';
		case 2: return 'U';
		case 3: return 'D';
		}
		assert(false); // unreachable
		return -1;
    }
};

template <typename Alphabets>
class aho_corasick {
    static const int invalid_idx = -1;

    struct PMA {
        int fail;
        std::vector<int> next, accept;
    
        PMA() : fail(invalid_idx), next(Alphabets::size, invalid_idx) {}
    };

public:
    aho_corasick(std::vector<std::string> const& ts)
    : K(ts.size()) {
        const int root_idx = 0;
        nodes.push_back(std::make_unique<PMA>()); // root node
        nodes[root_idx]->fail = root_idx; // root idx
        for(int i = 0; i < K; ++i) {
            int now = root_idx;
            for(auto cc : ts[i]) {
                int c = Alphabets::convert(cc);
                if(nodes[now]->next[c] == invalid_idx) {
                    nodes[now]->next[c] = static_cast<int>(nodes.size());
                    nodes.push_back(std::make_unique<PMA>());
                }
                now = nodes[now]->next[c];
            }
            nodes[now]->accept.push_back(i);
        }

        std::queue<int> que;
        for(int c = 0; c < Alphabets::size; ++c) {
            if(nodes[root_idx]->next[c] != invalid_idx) {
                nodes[nodes[root_idx]->next[c]]->fail = root_idx;
                que.push(nodes[root_idx]->next[c]);
            }
        }
        while(!que.empty()) {
            int now = que.front();
            que.pop();
            for(int c = 0; c < Alphabets::size; ++c) {
                if(nodes[now]->next[c] != invalid_idx) {
                    que.push(nodes[now]->next[c]);
                    int nxt = transition(nodes[now]->fail, Alphabets::convert_inv(c));
                    nodes[nodes[now]->next[c]]->fail = nxt;
                    for(auto ac : nodes[nxt]->accept) {
                        nodes[nodes[now]->next[c]]->accept.push_back(ac);
                    }
                }
            }
        }
    }

    int transition(int node_idx, char cc) {
        assert(0 <= node_idx && node_idx < static_cast<int>(nodes.size()));
        int c = Alphabets::convert(cc);
        int now = node_idx;
        while(nodes[now]->next[c] == invalid_idx && now != 0) {
            now = nodes[now]->fail;
        }
        now = nodes[now]->next[c];
        if(now == invalid_idx) now = 0;
        return now;
    }

    bool is_accept(int node_idx) const {
        assert(0 <= node_idx && node_idx < static_cast<int>(nodes.size()));
        return nodes[node_idx]->accept.size() != 0;
    }

    std::vector<std::vector<int>> match(std::string const& s) {
        std::vector<std::vector<int>> res(K);
        int now = 0;
        for(int i = 0; i < static_cast<int>(s.size()); ++i) {
            now = transition(now, s[i]);
            for(auto k : nodes[now]->accept) {
                res[k].push_back(i);
            }
        }
        return res;
    }

    int node_size() const {
        return static_cast<int>(nodes.size());
    }

private:
    const int K;
    std::vector<std::unique_ptr<PMA>> nodes;
};



int main() {
    constexpr int INF = 1e9;
    constexpr int dx[4] = {0, 1, 0, -1};
    constexpr int dy[4] = {1, 0, -1, 0};
	const string dir = "DRUL";

    int N, M;
    while(cin >> N >> M, N) {
        vector<string> fld(N);
        for(int i = 0; i < N; ++i) {
            cin >> fld[i];
        }
        int P;
        cin >> P;
        vector<string> ban(P);
        for(int i = 0; i < P; ++i) {
            cin >> ban[i];
        }

        int sy = -1, sx = -1, gy = -1, gx = -1;
        for(int i = 0; i < N; ++i) {
            for(int j = 0; j < M; ++j) {
                if(fld[i][j] == 'S') {
                    sy = i;
                    sx = j;
                }
                if(fld[i][j] == 'G') {
                    gy = i;
                    gx = j;
                }
            }
        }

        aho_corasick<alphabets> aho(ban);
        auto dist = table(N, M, aho.node_size(), INF);
        dist[sy][sx][0] = 0;
        using state = tuple<int, int, int>;
        queue<state> que;
        que.emplace(sy, sx, 0);
        while(!que.empty()) {
            int y, x, node;
            tie(y, x, node) = que.front();
            que.pop();
            for(int i = 0; i < 4; ++i) {
                int ny = y + dy[i], nx = x + dx[i];
                if(ny < 0 || N <= ny || nx < 0 || M <= nx) continue;
                if(fld[ny][nx] == '#') continue;

				int tnode = aho.transition(node, dir[i]);
				if(aho.is_accept(tnode)) continue;
				if(dist[ny][nx][tnode] != INF) continue;

				dist[ny][nx][tnode] = dist[y][x][node] + 1;
				que.emplace(ny, nx, tnode);
            }
        }

		const int ans = *min_element(begin(dist[gy][gx]), end(dist[gy][gx]));
		cout << (ans == INF ? -1 : ans) << endl;
    }
}


Measured memory_bytes: 3840