import java.util.*

fun main(args:Array<String>?): Unit {
    while(true){
        val (n, m) = readLine()!!.trim().split(' ').map(String::toInt)
        if (n == 0 && m == 0) return
        val state = Array(n){ readLine()!!.trim()}
        val start = (0 until n).mapNotNull{y -> (0 until m).find{x -> state[y][x] == 'S'}?.let{x -> Point(x, y)}}.first()
        val goal = (0 until n).mapNotNull{y -> (0 until m).find{x -> state[y][x] == 'G'}?.let{x -> Point(x, y)}}.first()
        val taboo = List(readLine()!!.toInt()){ readLine()!!.trim().map{
            when(it){
                'U' -> Direction.Up
                'D' -> Direction.Down
                'L' -> Direction.Left
                'R' -> Direction.Right
                else -> throw Exception()
            }
        }}.let{Automaton(it)}
        val memo = Array(n){Array(m){Array(taboo.size){Int.MAX_VALUE}}}
        memo[start.y][start.x][taboo.index] = 0
        val queue: Queue<Pair<Automaton, Point>> = LinkedList()
        queue.add(Pair(taboo, start))
        while (queue.isNotEmpty() && queue.first().second != goal){
            val (automaton, current) = queue.poll()
            for (dir in Direction.values()) {
                val nextState = automaton.next(dir)
                val nextPosition = current.move(dir)
                if (!nextState.isMatching &&
                        nextPosition.y in 0 until n &&
                        nextPosition.x in 0 until m &&
                        state[nextPosition.y][nextPosition.x] != '#' &&
                        memo[nextPosition.y][nextPosition.x][nextState.index] > memo[current.y][current.x][automaton.index] + 1) {
                    memo[nextPosition.y][nextPosition.x][nextState.index] = memo[current.y][current.x][automaton.index] + 1
                    queue.add(Pair(nextState, nextPosition))
                }
            }
        }
        println(
                memo[goal.y][goal.x].min()?.takeUnless{it == Int.MAX_VALUE} ?: -1
        )
    }
}
sealed class Automaton(val size: Int, val index: Int){
    abstract val isMatching: Boolean
    fun next(dir: Direction): Automaton = next(dir.toIndex)
    protected abstract fun next(dir: Int): Automaton
    private class Initial(size: Int, index: Int) : Automaton(size, index) {
        val child: Array<Inner?> = Array(4){null}
        override val isMatching: Boolean
            get() = false
        override fun next(dir: Int): Automaton {
            return child[dir] ?: this
        }
    }
    private class Inner(size: Int, index: Int, val child: Array<Automaton>, override val isMatching: Boolean): Automaton(size, index){
        override fun next(dir: Int): Automaton {
            return child[dir]
        }
    }
    companion object {
        operator fun invoke(taboos: Collection<List<Direction>>): Automaton {
            val head = Trie(false)
            var size = 1
            for (taboo in taboos){
                var trie = head
                for (dir in taboo){
                    if (trie.child[dir.toIndex] == null){
                        val child = Trie(false)
                        trie.child[dir.toIndex] = child
                        trie = child
                        ++size
                    }else {
                        trie = trie.child[dir.toIndex]!!
                    }
                }
                trie.hasPattern = true
            }
            var index = 0
            val first = Initial(size, index)
            val queue: Queue<Triple<Automaton, Inner, Trie>> = LinkedList()
            for (i in head.child.indices) if (head.child[i] != null){
                val child = Inner(size, ++index, Array(4){first}, head.child[i]!!.hasPattern)
                first.child[i] = child
                queue.add(Triple(first, child, head.child[i]!!))
            }
            while(queue.isNotEmpty()){
                val (nextLongestSuffix, current, trie) = queue.poll()
                for (i in trie.child.indices) {
                    if (trie.child[i] == null){
                        current.child[i] = nextLongestSuffix.next(i)
                    }else {
                        val child = Inner(size, ++index, Array(4){first}, nextLongestSuffix.next(i).isMatching || trie.child[i]!!.hasPattern)
                        current.child[i] = child
                        queue.add(Triple(nextLongestSuffix.next(i), child, trie.child[i]!!))
                    }
                }
            }
            return first
        }
        private class Trie(var hasPattern: Boolean) {
            var child: Array<Trie?> = Array(4){null}
        }
    }
}

data class Point(val x: Int, val y: Int) {
    fun move(dir: Direction): Point {
        return when(dir){
            Direction.Up -> Point(x, y - 1)
            Direction.Down -> Point(x, y + 1)
            Direction.Right -> Point(x + 1, y)
            Direction.Left -> Point(x - 1, y)
        }
    }
}

enum class Direction(val toIndex: Int) {
    Up(0), Down(1), Right(2), Left(3)
}


Measured memory_bytes: 83796