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

const int INF = 1e8;

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

string D = "DRUL";

// Aho-Corasick
const int var = 4;

int trans(char c) {
	switch (c)
	{
	case 'R': return 0;
	case 'D': return 1;
	case 'L': return 2;
	case 'U': return 3;
	default: break;
	}
	exit(EXIT_FAILURE);
}
struct node {
	node *fail;
	vector<node*> next;
	vector<int> ok;
	node() : fail(nullptr), next(var, nullptr) {}
};

node* getnext(node* p, char c) {
	while (p->next[trans(c)] == nullptr) p = p->fail;
	return p->next[trans(c)];
}

class Aho_Corasick {
	vector<int> unite(const vector<int>& a, const vector<int>& b) {
		vector<int> res;
		set_union(a.begin(), a.end(), b.begin(), b.end(), back_inserter(res));
		return res;
	}
	int K;
	node *root;
public:
	Aho_Corasick(const vector<string>& Ts) : K(Ts.size()), root(new node) {
		node *now;
		root->fail = root;
		for (int i = 0; i < K; i++) {
			auto &T = Ts[i];
			now = root;
			for (auto c : T) {
				if (now->next[trans(c)] == nullptr) {
					now->next[trans(c)] = new node;
				}
				now = now->next[trans(c)];
			}
			now->ok.push_back(i);
		}
		queue<node*> q;
		for (int i = 0; i < var; i++) {
			if (root->next[i] == nullptr) {
				root->next[i] = root;
			}
			else {
				root->next[i]->fail = root;
				q.push(root->next[i]);
			}
		}
		while (!q.empty()) {
			now = q.front(); q.pop();
			for (int i = 0; i < var; i++) {
				if (now->next[i] != nullptr) {
					node *nx = now->fail;
					while (nx->next[i] == nullptr) {
						nx = nx->fail;
					}
					now->next[i]->fail = nx->next[i];
					now->next[i]->ok = unite(now->next[i]->ok, nx->next[i]->ok);
					q.push(now->next[i]);
				}
			}
		}
	}
	node* getroot() const {
		return root;
	}
	vector<int> count(const string& S) const {
		vector<int> res(K);
		node *now = root;
		for (auto c : S) {
			while (now->next[trans(c)] == nullptr) {
				now = now->fail;
			}
			now = now->next[trans(c)];
			for (auto k : now->ok) {
				res[k]++;
			}
		}
		return res;
	}
};

using T = tuple<int, int, node*>;

int main()
{
	ios::sync_with_stdio(false), cin.tie(0);
	int n, m, p;
	while (cin >> n >> m, n | m) {
		vector<string> S(n);
		int sx = 0, sy = 0, gx = 0, gy = 0;
		for (int i = 0; i < n; i++) {
			cin >> S[i];
			for (int j = 0; j < (int)S[i].size(); j++) {
				if (S[i][j] == 'S') {
					sx = i;
					sy = j;
				}
				else if (S[i][j] == 'G') {
					gx = i;
					gy = j;
				}
			}
		}
		cin >> p;
		vector<string> pts(p);
		for (int i = 0; i < p; i++) {
			cin >> pts[i];
		}
		Aho_Corasick aho(pts);
		vector<vector<map<node*, int>>> f(n, vector<map<node*, int>>(m));
		queue<T> q;
		q.push(make_tuple(sx, sy, aho.getroot()));
		f[sx][sy][aho.getroot()] = 0;
		while (!q.empty()) {
			auto p = q.front(); q.pop();
			for (int i = 0; i < 4; i++) {
				int tx = get<0>(p) + dx[i], ty = get<1>(p) + dy[i];
				node *t = getnext(get<2>(p), D[i]);
				if (0 <= tx && tx < n && 0 <= ty && ty < m && S[tx][ty] != '#' && t->ok.empty() && f[tx][ty].count(t) == 0) {
					q.push(make_tuple(tx, ty, t));
					f[tx][ty][t] = f[get<0>(p)][get<1>(p)][get<2>(p)] + 1;
				}
			}
		}
		int res = INF;
		for (auto p : f[gx][gy]) {
			res = min(res, p.second);
		}
		cout << (res != INF ? res : -1) << endl;
	}
	return 0;
}

Measured memory_bytes: 9596