#include <bits/stdc++.h>
using namespace std;
const int N = 410;
struct edge {
  int to, next;
} e[N * N * 2], e2[N * N * 2];
int head[N], ecnt, vis[N], stk[N], top, dfn[N], low[N], dfsn, head2[N], ecnt2;
int scc, belong[N], Belong[N];
inline void adde(int from, int to) {
  from = Belong[from], to = Belong[to];
  e[++ecnt] = (edge){to, head[from]}, head[from] = ecnt;
}
inline void adde2(int from, int to) {
  e2[++ecnt2] = (edge){to, head2[from]}, head2[from] = ecnt2;
}
inline void Tarjan(int u, int ls) {
  stk[++top] = u, vis[u] = 1;
  dfn[u] = low[u] = ++dfsn;
  for (int i = head[u]; i; i = e[i].next)
    if (i != ls) {
      if (!dfn[e[i].to])
        Tarjan(e[i].to, i), low[u] = min(low[u], low[e[i].to]);
      else if (vis[e[i].to])
        low[u] = min(low[u], dfn[e[i].to]);
    }
  if (low[u] == dfn[u]) {
    scc++;
    int v = -1;
    while (v != u) {
      v = stk[top--];
      belong[v] = scc, vis[v] = 0;
    }
  }
}
inline void Clear(int n) {
  fill(head + 1, head + n + 1, 0), fill(dfn + 1, dfn + n + 1, 0),
      scc = ecnt = 0;
}
inline bool Just_DOIT(int n) {
  assert((n & 1) ^ 1);
  for (int i = 1; i <= n; i++)
    if (!dfn[Belong[i]]) Tarjan(Belong[i], 0);
  for (int i = 1; i <= n / 2; i++)
    if (belong[Belong[i]] == belong[Belong[i + n / 2]]) return false;
  return true;
}
int n;
inline int ID(int t, int x) { return t * n + x; }
inline void mark(int t, int x) { adde(ID(t ^ 1, x), ID(t, x)); }
inline void mark(int t1, int t2, int x, int y) {
  adde(ID(t1, x), ID(t2, y)), adde(ID(t2 ^ 1, y), ID(t1 ^ 1, x));
}
int nxt[30][2], vowel[30];
char s[N], t[N];
int T1[N * N], T2[N * N], from[N * N], to[N * N], m;
inline bool check(int cur) {
  Clear(n * 2);
  ecnt = ecnt2, memcpy(e, e2, sizeof(edge) * (ecnt2 + 1));
  for (int i = 1; i <= n * 2; i++) head[i] = head2[i];
  for (int i = 1; i <= cur; i++) mark(vowel[t[i] - 'a'], i);
  return Just_DOIT(n * 2);
}
char str[30];
int main() {
  scanf("%s", str + 1);
  int len = strlen(str + 1);
  int cur[2] = {-1, -1};
  for (int i = len; i >= 0; i--) {
    nxt[i][0] = cur[0], nxt[i][1] = cur[1];
    if (i) cur[str[i] == 'V'] = i - 1, vowel[i - 1] = str[i] == 'V';
  }
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n * 2; i++) Belong[i] = i;
  for (int i = 1; i <= m; i++) {
    char c1, c2;
    scanf("%d %c %d %c", &from[i], &c1, &to[i], &c2);
    T1[i] = c1 == 'V', T2[i] = c2 == 'V';
  }
  for (int i = 1; i <= m; i++) mark(T1[i], T2[i], from[i], to[i]);
  if (!Just_DOIT(n * 2)) return puts("-1"), 0;
  for (int i = 1; i <= n * 2; i++) Belong[i] = belong[i];
  for (int i = 1; i <= n * 2; i++)
    for (int j = head[i]; j; j = e[j].next) {
      int a = belong[i], b = belong[e[j].to];
      if (a != b) adde2(a, b);
    }
  scanf("%s", s + 1);
  int pos = -1;
  for (int i = n; i >= 0; i--) {
    for (int j = 1; j <= i; j++) t[j] = s[j];
    if (i != n) t[i + 1] = nxt[s[i + 1] - 'a' + 1][0] + 'a';
    if (t[i + 1] != 'a' - 1 && check(min(n, i + 1))) {
      pos = i;
      break;
    }
    if (i != n) t[i + 1] = nxt[s[i + 1] - 'a' + 1][1] + 'a';
    if (i != n && t[i + 1] != 'a' - 1 && check(min(n, i + 1))) {
      pos = i;
      break;
    }
  }
  if (!~pos) return puts("-1"), 0;
  for (int i = 1; i <= pos; i++) t[i] = s[i];
  for (int i = pos + 1; i <= n; i++) {
    char a = i == pos + 1 ? nxt[s[i] - 'a' + 1][0] : nxt[0][0],
         b = i == pos + 1 ? nxt[s[i] - 'a' + 1][1] : nxt[0][1];
    a += 'a', b += 'a';
    if (a == 'a' - 1) a = 'z' + 1;
    if (b == 'a' - 1) b = 'z' + 1;
    if (a > b) swap(a, b);
    t[i] = a;
    if (t[i] != 'z' + 1 && check(i)) continue;
    t[i] = b;
    if (t[i] < 'a' || t[i] > 'z') return puts("-1"), 0;
  }
  for (int i = 1; i <= n; i++) putchar(t[i]);
}
