#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum DIR{
	North,
	East,
	South,
	West,
};

struct Node{
	int num,parent_id,children[4],suffix_link,depth;
	bool finish_FLG;
	DIR pattern[10];
};

struct Data{
	void set(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};

struct Info{
	Info(int arg_row,int arg_col,int arg_sum_cost,int arg_node_loc){
		row = arg_row;
		col = arg_col;
		sum_cost = arg_sum_cost;
		node_loc = arg_node_loc;
	}
	bool operator<(const struct Info &arg) const{
		return sum_cost > arg.sum_cost;
	}
	int row,col,sum_cost,node_loc;
};


int H,W,POW[11];
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
int table[128],min_cost[50][50][200];
DIR dir_table[4] = {North,East,South,West};

char base_map[50][51];
Node nodes[200];
Data start,goal;
map<int,int> MAP;


bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
	else{
		return false;
	}
}


void debug(DIR dir){

	switch(dir){
	case North:
		printf("U");
		break;
	case East:
		printf("R");
		break;
	case South:
		printf("D");
		break;
	case West:
		printf("L");
		break;
	}
}

void func(){

	for(int i = 0; i < 200; i++){
		nodes[i].finish_FLG = false;
		for(int k = 0; k < 4; k++)nodes[i].children[k] = -1;
	}

	for(int row = 0; row < H; row++){
		scanf("%s",base_map[row]);
		for(int col = 0; col < W; col++){
			if(base_map[row][col] == 'S'){

				start.set(row,col);

			}else if(base_map[row][col] == 'G'){

				goal.set(row,col);

			}
		}
	}

	int P;
	scanf("%d",&P);

	nodes[0].parent_id = -1;
	nodes[0].num = 0;
	nodes[0].depth = 0;
	int node_index = 1,tmp_ch,tmp_loc,parent_id,tmp_index;
	char buf[11];
	MAP.clear();


	for(int loop = 0; loop < P; loop++){

		scanf("%s",buf);

		tmp_index = 0;
		tmp_ch = table[buf[tmp_index]];

		tmp_loc = 0;
		tmp_index = 0;

		while(true){

			parent_id = tmp_loc;

			if(nodes[tmp_loc].children[tmp_ch] == -1){

				nodes[tmp_loc].children[tmp_ch] = node_index++;
			}

			tmp_loc = nodes[tmp_loc].children[tmp_ch];

			nodes[tmp_loc].parent_id = parent_id;

			for(int i = 0; i < nodes[parent_id].depth; i++){
				nodes[tmp_loc].pattern[i] = nodes[parent_id].pattern[i];
			}
			nodes[tmp_loc].pattern[nodes[parent_id].depth] = dir_table[tmp_ch];
			nodes[tmp_loc].depth = nodes[parent_id].depth+1;

			tmp_index++;

			nodes[tmp_loc].num = -1;
			for(int  i = 0; i < nodes[tmp_loc].depth; i++){
				nodes[tmp_loc].num += (nodes[tmp_loc].pattern[i]+1)*POW[i];
			}

			MAP[nodes[tmp_loc].num] = tmp_loc;

			if(buf[tmp_index] == '\0'){
				nodes[tmp_loc].finish_FLG = true;

				break;
			}
			tmp_ch = table[buf[tmp_index]];
		}
	}

	int tmp,start_pos;
	bool Found;

	for(int i = 1; i < node_index; i++){

		Found = false;
		start_pos = 1;

		while(start_pos < nodes[i].depth){

			tmp = -1;
			for(int k = start_pos; k < nodes[i].depth; k++){
				tmp += (nodes[i].pattern[k]+1)*POW[k-start_pos];
			}

			auto at = MAP.find(tmp);
			if(at != MAP.end()){
				Found = true;
				break;
			}
			start_pos++;
		}

		if(!Found){
			nodes[i].suffix_link = 0;
		}else{

			nodes[i].suffix_link = MAP[tmp];
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			for(int node_loc = 0; node_loc < node_index; node_loc++)min_cost[row][col][node_loc] = BIG_NUM;
		}
	}

	min_cost[start.row][start.col][0] = 0;

	priority_queue<Info> Q;
	Q.push(Info(start.row,start.col,0,0));

	int next_node_pos,adj_row,adj_col;
	DIR next_dir;

	bool FLG;

	int calc;

	while(!Q.empty()){

		if(Q.top().row == goal.row && Q.top().col == goal.col){

			printf("%d\n",Q.top().sum_cost);
			return;

		}else if(Q.top().sum_cost > min_cost[Q.top().row][Q.top().col][Q.top().node_loc]){
			Q.pop();
		}else{

			for(int i = 0; i < 4; i++){
				adj_row = Q.top().row+diff_row[i];
				adj_col = Q.top().col+diff_col[i];

				if(rangeCheck(adj_row,adj_col) == false || base_map[adj_row][adj_col] == '#')continue;

				switch(i){
				case 0:
					next_dir = North;
					break;
				case 1:
					next_dir = West;
					break;
				case 2:
					next_dir = East;
					break;
				case 3:
					next_dir = South;
					break;
				}

				if(nodes[Q.top().node_loc].children[next_dir] != -1){

					next_node_pos = nodes[Q.top().node_loc].children[next_dir];

				}else{

					if(Q.top().node_loc == 0){

						next_node_pos = 0;

						if(min_cost[adj_row][adj_col][next_node_pos] > Q.top().sum_cost+1){
							min_cost[adj_row][adj_col][next_node_pos] = Q.top().sum_cost+1;
							Q.push(Info(adj_row,adj_col,Q.top().sum_cost+1,next_node_pos));
						}

						continue;
					}

					tmp = nodes[Q.top().node_loc].suffix_link;

					while(tmp != 0 && nodes[tmp].children[next_dir] == -1){
						tmp = nodes[tmp].suffix_link;
					}

					if(tmp == 0){
						if(nodes[tmp].children[next_dir] == -1){
							next_node_pos = 0;
						}else{
							next_node_pos = nodes[tmp].children[next_dir];
						}

					}else{
						next_node_pos = nodes[tmp].children[next_dir];
					}
				}

				FLG = true;

				tmp = next_node_pos;

				while(tmp != 0){
					if(nodes[tmp].finish_FLG){

						FLG = false;
						break;
					}
					tmp = nodes[tmp].suffix_link;
				}

				if(!FLG)continue;

				if(min_cost[adj_row][adj_col][next_node_pos] > Q.top().sum_cost+1){
					min_cost[adj_row][adj_col][next_node_pos] = Q.top().sum_cost+1;
					Q.push(Info(adj_row,adj_col,Q.top().sum_cost+1,next_node_pos));
				}
			}
			Q.pop();
		}
	}
	printf("-1\n");
}


int main(){

	for(int i = 0; i < 11; i++)POW[i] = pow(4,i);

	table['U'] = North;
	table['R'] = East;
	table['D'] = South;
	table['L'] = West;

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		func();
	}
	return 0;
}



Measured memory_bytes: 5384