#include<iostream>
#include<string>
#include<queue>
#include<vector>
#include<tuple>
using namespace std;
int H, W, K, x[60][60], dist[60][60][200], sx, sy, gx, gy, dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };
string S[10], dir = "DRUL";
vector<tuple<string, int, int>>vec;
vector<tuple<int, int, int>> X[60][60][200];
vector<pair<int, int>>banned[200];
void build_banned() {
	int cnt1 = 1;
	vec.push_back(make_tuple("", 0, 0));
	for (int i = 0; i < K; i++) {
		for (int j = 0; j <= S[i].size(); j++) {
			string F = S[i].substr(0, j);
			bool OK = true;
			for (int k = 0; k < vec.size(); k++) {
				if (get<0>(vec[k]) == F) {
					OK = false;
					if (j == S[i].size()) { get<2>(vec[k]) = 1; }
				}
			}
			if (OK == true && j != S[i].size()) { vec.push_back(make_tuple(F, cnt1, 0)); cnt1++; }
			if (OK == true && j == S[i].size()) { vec.push_back(make_tuple(F, cnt1, 1)); cnt1++; }
		}
	}
	for (int i = 0; i < vec.size(); i++) {
		for (int j = 0; j < 4; j++) {
			string W2 = get<0>(vec[i]); W2 += dir[j];
			bool OK = true; int to = 0;
			while (W2.size() >= 1) {
				for (int k = 0; k < vec.size(); k++) {
					string W3 = get<0>(vec[k]);
					if (W3 == W2 && get<2>(vec[k]) == 1) { OK = false; }
					if (W3 == W2 && get<2>(vec[k]) == 0) {
						if (get<0>(vec[to]).size() < W2.size())to = k;
					}
				}
				W2 = W2.substr(1, W2.size() - 1);
			}
			if (OK == true)banned[i].push_back(make_pair(to, j));
		}
	}
}
void add_edges() {
	for (int i = 1; i <= H; i++) {
		for (int j = 1; j <= W; j++) {
			for (int k = 0; k < vec.size(); k++) {
				if (get<2>(vec[k]) == 1)continue;
				for (int l = 0; l < 4; l++) {
					int cx = i + dx[l], cy = j + dy[l];
					if (cx <= 0 || cy <= 0 || cx > H || cy > W || x[cx][cy] == 2)continue;
					for (int m = 0; m < banned[k].size(); m++) {
						if (banned[k][m].second == l)X[i][j][k].push_back(make_tuple(cx, cy, banned[k][m].first));
					}
				}
			}
		}
	}
}
int bfs() {
	queue<tuple<int, int, int>>Q;
	for (int i = 0; i < 60; i++) { for (int j = 0; j < 60; j++) { for (int k = 0; k < 200; k++)dist[i][j][k] = 999999999; } }
	Q.push(make_tuple(sx, sy, 0)); dist[sx][sy][0] = 0;
	while (!Q.empty()) {
		int a1 = get<0>(Q.front()), a2 = get<1>(Q.front()), a3 = get<2>(Q.front()); Q.pop();
		for (int i = 0; i < X[a1][a2][a3].size(); i++) {
			int tox = get<0>(X[a1][a2][a3][i]), toy = get<1>(X[a1][a2][a3][i]), toz = get<2>(X[a1][a2][a3][i]);
			if (dist[tox][toy][toz] == 999999999) {
				dist[tox][toy][toz] = dist[a1][a2][a3] + 1;
				Q.push(make_tuple(tox, toy, toz));
			}
		}
	}
	int maxn = 999999999;
	for (int i = 0; i < vec.size(); i++)maxn = min(maxn, dist[gx][gy][i]);
	return maxn;
}
int main() {
	while (true) {
		vec.clear(); for (int i = 0; i < 3600; i++)x[i / 60][i % 60] = 0;
		for (int i = 0; i < 60; i++) { for (int j = 0; j < 60; j++) { for (int k = 0; k < 200; k++)X[i][j][k].clear(); } }
		for (int i = 0; i < 200; i++)banned[i].clear();
		cin >> H >> W; if (H == 0 && W == 0)break;
		for (int i = 1; i <= H; i++) {
			for (int j = 1; j <= W; j++) {
				char c; cin >> c;
				if (c == '.') { x[i][j] = 1; }
				if (c == '#') { x[i][j] = 2; }
				if (c == 'S') { x[i][j] = 1; sx = i; sy = j; }
				if (c == 'G') { x[i][j] = 1; gx = i; gy = j; }
			}
		}
		cin >> K; for (int i = 0; i < K; i++) { cin >> S[i]; }
		build_banned();
		add_edges();
		int ans = bfs(); if (ans == 999999999)ans = -1;
		cout << ans << endl;
	}
	return 0;
}

Measured memory_bytes: 34720