#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,
};

enum Type{
	TRUE,
	FALSE,
	UNKNOWN,
};

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

struct SL{
	SL(int arg_node_id,DIR arg_tmp_dir){
		node_id = arg_node_id;
		tmp_dir = arg_tmp_dir;
	}
	int node_id;
	DIR tmp_dir;
};

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];
Type type[200];
Data start,goal;


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;
		nodes[i].suffix_link = 0;
		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);

	int root = 0;

	nodes[root].parent_id = -1;
	nodes[root].depth = 0;
	int node_index = 1,tmp_ch,tmp_loc,parent_id,tmp_index;
	char buf[11];


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

		scanf("%s",buf);

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

		tmp_loc = root;
		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;
			nodes[tmp_loc].depth = nodes[parent_id].depth+1;

			tmp_index++;

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

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

	int tmp,start_pos;
	bool Found;

	queue<SL> MAKE_SL;
	for(int i = 0; i < 4; i++){
		if(nodes[root].children[i] != -1){
			MAKE_SL.push(SL(nodes[root].children[i],dir_table[i]));
		}
	}

	int node_id;
	DIR tmp_dir;
	while(!MAKE_SL.empty()){
		node_id = MAKE_SL.front().node_id;
		tmp_dir = MAKE_SL.front().tmp_dir;
		MAKE_SL.pop();

		for(int i = 0; i < 4; i++){
			if(nodes[node_id].children[i] != -1){
				MAKE_SL.push(SL(nodes[node_id].children[i],dir_table[i]));
			}
		}

		for(tmp_loc = nodes[nodes[node_id].parent_id].suffix_link; tmp_loc != root; tmp_loc = nodes[tmp_loc].suffix_link){
			if(nodes[tmp_loc].children[tmp_dir] != -1){
				break;
			}
		}
		if(tmp_loc == root){
			if(nodes[root].children[tmp_dir] != -1){
				if(node_id == nodes[root].children[tmp_dir]){
					nodes[node_id].suffix_link = root;
				}else{
					nodes[node_id].suffix_link = nodes[root].children[tmp_dir];
				}
			}else{
				nodes[node_id].suffix_link = root;
			}
		}else{
			nodes[node_id].suffix_link = nodes[tmp_loc].children[tmp_dir];
		}
	}

	for(int i = 0; i < node_index; i++){
		type[i] = UNKNOWN;
	}

	type[root] = FALSE;

	queue<int> CHECK;
	for(int i = 0; i < 4; i++){
		if(nodes[root].children[i] != -1){
			if(nodes[nodes[root].children[i]].finish_FLG){
				type[nodes[root].children[i]] = TRUE;
			}else{
				type[nodes[root].children[i]] = FALSE;
			}
			CHECK.push(nodes[root].children[i]);
		}
	}

	while(!CHECK.empty()){
		node_id = CHECK.front();
		CHECK.pop();

		for(int i = 0; i < 4; i++){
			if(nodes[node_id].children[i] != -1){
				CHECK.push(nodes[node_id].children[i]);
			}
		}

		if(nodes[node_id].finish_FLG){
			type[node_id] = TRUE;
		}else{
			for(tmp_loc = nodes[node_id].suffix_link; tmp_loc != root; tmp_loc = nodes[tmp_loc].suffix_link){
				if(type[tmp_loc] != UNKNOWN)break;
			}
			type[node_id] = type[tmp_loc];
		}
	}
	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;

				if(type[next_node_pos] == TRUE)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: 5396