#include "bits/stdc++.h"

#define REP(i, n) for (int i = 0; i < n; ++i)
// https://onlinejudge.u-aizu.ac.jp/status/users/EtoNagisa/submissions/1/2212/judge/3966278/C++14
using namespace std;

#include "bits/stdc++.h"

struct lower_alphabet {
  static constexpr std::size_t char_size = 26;
  static constexpr char min_char = 'a';
};
struct upper_alphabet {
  static constexpr std::size_t char_size = 26;
  static constexpr char min_char = 'A';
};
struct general_char {
  static constexpr std::size_t char_size = 256;
  static constexpr char min_char = 0;
};
template <typename character>
class aho_corasick {
 public:
  static constexpr std::size_t invalid_index = -1;
  struct PMA {
    std::size_t fail;  // index of state correspond to fail suffix
    std::vector<std::size_t> next, accept;
    std::set<std::size_t> r_fail;
    PMA() : fail(0), next(character::char_size, invalid_index) {}
  };
  std::vector<PMA> nodes;
  std::size_t cnt;

  aho_corasick() : cnt(0) {}
  void build(const std::vector<std::string> &dict) {
    add_node();
    for (std::size_t i = 0; i < dict.size(); ++i) {
      std::size_t now = 0;
      for (std::size_t j = 0; j < dict[i].size(); ++j) {
        std::size_t t = static_cast<size_t>(dict[i][j] - character::min_char);
        if (nodes[now].next[t] == invalid_index) {
          std::size_t next = size();
          add_node();
          nodes[now].next[t] = next;
        }
        now = nodes[now].next[t];
      }
      nodes[now].accept.push_back(i);
    }
    std::queue<std::size_t> q;
    for (std::size_t i = 0; i < character::char_size; ++i) {
      if (nodes[0].next[i] == invalid_index) {
        nodes[0].next[i] = 0;
      } else {
        set_fail(nodes[0].next[i], 0);
        q.push(nodes[0].next[i]);
      }
    }
    while (!q.empty()) {
      std::size_t p = q.front();
      q.pop();
      for (std::size_t i = 0; i < character::char_size; ++i) {
        if (nodes[p].next[i] != invalid_index) {
          std::size_t tmp = next(nodes[p].fail, i + character::min_char);
          set_fail(nodes[p].next[i], tmp);
          for (std::size_t ac : nodes[tmp].accept) {
            nodes[nodes[p].next[i]].accept.push_back(ac);
          }
          q.push(nodes[p].next[i]);
        }
      }
    }
  }
  void add(const std::string &s) {
    std::size_t start = -1, now = 0;
    for (std::size_t i = 0; i < s.size(); ++i) {
      std::size_t t = static_cast<size_t>(s[i] - character::min_char);
      if (nodes[now].next[t] == invalid_index) {
        start = i;
        break;
      }
      now = nodes[now].next[t];
    }
    for (std::size_t i = start; i < s.size(); ++i) {
      std::size_t t = static_cast<size_t>(s[i] - character::min_char);
      std::size_t nxt = size();
      add_node();
      nodes[now].next[t] = nxt;
      std::size_t tmp = next(nodes[now].fail, s[i]);
      set_fail(nxt, tmp);
      for (std::size_t ac : nodes[tmp]) {
        nodes[nxt].accept.push_back(ac);
      }

      for (std::size_t p : nodes[now].r_fail) {
        if (nodes[p].next[t] != invalid_index) {
          set_fail(nodes[p].next[t], nxt);
        }
      }
      now = nxt;
    }
  }
  std::size_t size() const { return cnt; }
  std::size_t next(std::size_t now, char c) const {
    std::size_t t = static_cast<std::size_t>(c - character::min_char);
    while (nodes[now].next[t] == invalid_index) now = nodes[now].fail;
    return nodes[now].next[t];
  }
  std::vector<std::vector<std::size_t>> match(const std::string &s) const {
    std::size_t now = 0;
    std::vector<std::vector<std::size_t>> ret(s.size());
    for (std::size_t i = 0; i < s.size(); ++i) {
      now = next(now, s[i]);
      for (auto ac : nodes[now].accept) {
        ret[i].push_back(ac);
      }
    }
  }

 private:
  void add_node() {
    nodes.emplace_back();
    cnt++;
  }
  void set_fail(std::size_t from, std::size_t to) {
    nodes[nodes[from].fail].r_fail.erase(from);
    nodes[from].fail = to;
    nodes[to].r_fail.insert(from);
  }
};
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
string mv = "DRUL";
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, m;
  while (cin >> n >> m, n) {
    vector<string> v(n);
    REP(i, n) cin >> v[i];
    int qu;
    cin >> qu;
    vector<string> p(qu);
    REP(i, qu) cin >> p[i];
    aho_corasick<upper_alphabet> ac;
    ac.build(p);
    int sx = -1, sy = -1, tx = -1, ty = -1;
    REP(i, n) REP(j, m) {
      if (v[i][j] == 'S') {
        sx = i;
        sy = j;
      } else if (v[i][j] == 'G') {
        tx = i;
        ty = j;
      }
    }
    int k = ac.nodes.size();
    vector<vector<vector<int>>> dp(n,
                                   vector<vector<int>>(m, vector<int>(k, 1e9)));
    dp[sx][sy][0] = 0;
    queue<pair<pair<int, int>, int>> q;
    q.push({{sx, sy}, 0});
    while (!q.empty()) {
      auto c = q.front();
      q.pop();
      int x = c.first.first, y = c.first.second, s = c.second;
      REP(d, 4) {
        int nx = x + dx[d], ny = y + dy[d], ns = ac.next(s, mv[d]);
        if (nx < 0 || nx >= n || ny < 0 || ny >= m || v[nx][ny] == '#' ||
            ac.nodes[ns].accept.size() > 0)
          continue;
        if (dp[nx][ny][ns] > dp[x][y][s] + 1) {
          dp[nx][ny][ns] = dp[x][y][s] + 1;
          q.push({{nx, ny}, ns});
        }
      }
    }
    int ans = 1e9;
    REP(i, k) ans = min(ans, dp[tx][ty][i]);
    if (ans == 1e9)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
}



Measured memory_bytes: 3800