#pragma comment(linker, "/stack:20000000")
#define _CRT_SECURE_NO_WARNINGS
# include <iostream>
# include <cmath>
# include <algorithm>
# include <cstdio>
# include <cstring>
# include <string>
# include <cstdlib>
# include <vector>
# include <bitset>
# include <map>
# include <queue>
# include <ctime>
# include <stack>
# include <set>
# include <list>
# include <deque>
# include <functional>
# include <sstream>
# include <fstream>
# include <complex>
# include <numeric>
using namespace std;

// Let's define unordered map
# ifdef __GNUC__
# if __cplusplus > 199711L
# include <unordered_map>
# else
# include <tr1/unordered_map>
using namespace std::tr1;
# endif
# else
# include <unordered_map>
# endif

#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL_((0,__VA_ARGS__, 5,4,3,2,1))
#define VA_NUM_ARGS_IMPL_(tuple) VA_NUM_ARGS_IMPL tuple
#define VA_NUM_ARGS_IMPL(_0,_1,_2,_3,_4,_5,N,...) N

#define macro_dispatcher(macro, ...) macro_dispatcher_(macro, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(macro, nargs) macro_dispatcher__(macro, nargs)
#define macro_dispatcher__(macro, nargs) macro_dispatcher___(macro, nargs)
#define macro_dispatcher___(macro, nargs) macro ## nargs

#define DBN1(a)			std::cerr<<#a<<"="<<(a)<<"\n"
#define DBN2(a,b)		std::cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<"\n"
#define DBN3(a,b,c)		std::cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<"\n"
#define DBN4(a,b,c,d)	std::cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<"\n"
#define DBN5(a,b,c,d,e)	std::cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<"\n"

#define DEB(x) std::cerr<<#x<<"="<<(x)<<"  "

#define DB(x) DEB(x)
#define DBN(...) macro_dispatcher(DBN, __VA_ARGS__)(__VA_ARGS__)
#define DA(a,n) cout<<#a<<"=["; printarray(a,n); cout<<"]\n"
#define DAR(a,n,s) cout<<#a<<"["<<s<<"-"<<n-1<<"]=["; printarray(a,n,s); cout<<"]\n"

double __begin;
#define DTIME(ccc) __begin = clock(); ccc; std::cerr<<"Time of work = "<<(clock()-__begin)/CLOCKS_PER_SEC<<std::endl;

#define mp make_pair
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<long long,long long> pll;
typedef vector<int> vi;
typedef vector<long long> vll;

template<typename T1,typename T2,typename T3>
struct triple{T1 a;T2 b;T3 c;triple(){};triple(T1 _a,T2 _b, T3 _c):a(_a),b(_b),c(_c){}};
#define tri triple<int,int,int>
#define trl triple<ll,ll,ll>
template<typename T1,typename T2,typename T3>
bool operator<(const triple<T1,T2,T3> &t1,const triple<T1,T2,T3> &t2){if (t1.a!=t2.a) return t1.a<t2.a; else if (t1.b != t2.b) return t1.b<t2.b; else return t1.c < t2.c; }
template<typename T1, typename T2, typename T3>
inline std::ostream& operator << (std::ostream& os, const triple<T1, T2, T3>& t){ return os << "(" << t.a << ", " << t.b << ", " << t.c << ")"; }

#define FI(n) for(int i=0;i<n;i++)
#define FJ(n) for(int j=0;j<n;j++)

//STL containers
#define foreach(v, c)               for( auto v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ((b).find(a) != (b).end())
#define in2(a,b)                    (find(all(b),a) != (b).end())
#define sz(a)                       ((int)(a.size()))
#define svi(vec,n) FI(n) S(vec[y])
#define svl(vec,n) FI(n) Sl(vec[y])

//int some_primes[10] = {100271, 500179, 1000003, 2000227, 5000321}
//fill char arrays
#define fill(a,v)                    memset(a, v, sizeof (a))

inline int bits_count(int v){v=v-((v>>1)&0x55555555);v=(v&0x33333333)+((v>>2)&0x33333333);return((v+(v>>4)&0xF0F0F0F)*0x1010101)>>24;}
inline int bits_count(ll v){ int t = v >> 32; int p = (v & ((1LL << 32) - 1)); return bits_count(t) + bits_count(p); }
unsigned int reverse_bits(register unsigned int x){x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));return((x >> 16) | (x << 16));}
inline int sign(int x){return (x >> 31) | (-x >> 31);}
inline bool ispow2(int x){return (x!=0 && (x&(x-1))==0);}
#define checkbit(n,b)        ( (n >> b) & 1)
#define INDEX(arr,ind)       (lower_bound(all(arr),ind)-arr.begin())
#define sor(a)  sort(all(a))
#define rsor(a) sort(all(a)); reverse(all(a));

//STL output ********************************
template<typename T1,typename T2>inline std::ostream& operator << (std::ostream& os, const std::pair<T1, T2>& p){return os << "(" << p.first << ", " << p.second << ")";}
template<typename T>inline std::ostream &operator<<(std::ostream &os,const std::vector<T>& v){bool first=true;os<<"[";for(unsigned int i=0;i<v.size();i++){if(!first)os<<", ";os<<v[i];first=false;}return os<<"]";}
template<typename T>inline std::ostream &operator<<(std::ostream &os,const std::set<T>&v){bool first=true;os << "[";for(typename std::set<T>::const_iterator ii=v.begin();ii!=v.end();++ii){if(!first)os<<", ";os<<*ii;first=false;}return os<<"]";}
template<typename T1, typename T2>inline std::ostream &operator << (std::ostream & os,const std::map<T1, T2>& v){bool first = true; os << "[";for (typename std::map<T1,T2>::const_iterator ii =v.begin();ii!=v.end();++ii){if(!first)os<<", ";os<<*ii;first=false;}return os<<"]";}
template<typename T,typename T2>void printarray(T  a[],T2 sz,T2 beg=0){for(T2 i=beg;i<sz;i++) cout<<a[i]<<" ";cout<<endl;}

#define FREIN(FILE) freopen(FILE,"rt",stdin)
#define FREOUT(FILE) freopen(FILE,"wt",stdout)

#define sqr(x) ((x)*(x))
#define sqrt(x) sqrt(1.0*(x))
#define pow(x,n) pow(1.0*(x),n)

inline ll powmod(ll x,ll n, ll _mod){ll res=1;while(n){if(n&1)res=(res*x)%_mod;x=(x*x)%_mod;n>>=1;}return res;}
inline ll gcd(ll a,ll b){ll t;while(b){a=a%b;t=a;a=b;b=t;}return a;}
inline int gcd(int a,int b){int t;while(b){a=a%b;t=a;a=b;b=t;}return a;}
inline ll lcm(int a,int b){return a/gcd(a,b)*(ll)b;}
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll gcd(ll a,ll b,ll c){return gcd(gcd(a,b),c);}
inline int gcd(int a,int b,int c){return gcd(gcd(a,b),c);}
inline ll lcm(ll a,ll b,ll c){return lcm(lcm(a,b),c);}
inline ll lcm(int a,int b,int c){return lcm(lcm(a,b),(ll)c);}

inline ll max(ll a,ll b){return (a>b)?a:b;}
inline int max(int a,int b){return (a>b)?a:b;}
inline double max(double a,double b){return (a>b)?a:b;}
inline ll max(ll a,ll b,ll c){return max(a,max(b,c));}
inline int max(int a,int b,int c){return max(a,max(b,c));}
inline double max(double a,double b,double c){return max(a,max(b,c));}
inline ll min(ll a,ll b){return (a<b)?a:b;}
inline int min(int a,int b){return (a<b)?a:b;}
inline double min(double a,double b){return (a<b)?a:b;}
inline ll min(ll a,ll b,ll c){return min(a,min(b,c));}
inline int min(int a,int b,int c){return min(a,min(b,c));}
inline double min(double a,double b,double c){return min(a,min(b,c));}

template<class T>
inline void getar(T a, int n, int m){ for (int i = 0; i < n; i++) for (int j = 0; j < m;++j) { scanf("%d", &a[i][j]); } }
inline void getar(int *a, int n){ for (int ii = 0; ii < n; ii++){ scanf("%d", a + ii); } }
inline void getar(pii *a, int n){ for (int ii = 0; ii < n; ii++){ scanf("%d%d", &a[ii].first, &a[ii].second); } }
inline void getar(ll *a, int n){ for (int ii = 0; ii < n; ii++){ scanf("%I64d", a + ii); } }
template<class T>
inline void cinarr(T &a, int n){ for (int i=0;i<n;++i) cin >> a[i];}
// Useful constants

#define INF			1011111111
#define EPS			(double)1e-15
#define mod			1000000007
#define PI			3.14159265358979323
//*******************************************************************************/

bool voc[10010];
vector<pii> v[201][2];
bool isbad[201][2];
bool used[201][2];
int w[201][2];
bool way[201][2][201][2];
bool canbe[201][2][201][2];
bool isb = false;
bool wentb[201];
bool mustb[201];
int sx, sa;
void go(int x, int a) {
    used[x][a] = true;
    way[sx][sa][x][a] = true;
    for (auto to : v[x][a]) {
        if (!used[to.first][to.second]) {
            go(to.first, to.second);
        }
    }
}
void DIE() {
    cout << -1 << endl;
    exit(0);
}
string s;
int n;
int l;
int ans[202];
int iter = 0;
bool place(int cur, bool can = false) {
    ++iter;
    if (cur == n) return true;
    for (int i = cur; i < n; ++i) {
        int t = (w[i][0] == cur) + (w[i][1] == cur);
        if (t == 0) return false;
    }
    if (can) {
        ans[cur] = 0;
    } else {
        ans[cur] = s[cur];
    }
    int curt = voc[ans[cur]];
    if (w[cur][curt] == cur) {
        for (int x = cur + 1; x < n; ++x) {
            for (int a = 0; a < 2; ++a) {
                w[x][a] += canbe[cur][curt][x][a];
            }
        }
        bool res = place(cur + 1, can);
        for (int x = cur + 1; x < n; ++x) {
            for (int a = 0; a < 2; ++a) {
                w[x][a] -= canbe[cur][curt][x][a];
            }
        }
        if (res) {
            return true;
        }
    }
    ++ans[cur];
    if (ans[cur] == l) return false;
    while(can == false)
    {
        curt = voc[ans[cur]];
        if (w[cur][curt] < cur) break;
        for (int x = cur + 1; x < n; ++x) {
            for (int a = 0; a < 2; ++a) {
                w[x][a] += canbe[cur][curt][x][a];
            }
        }
        bool res = place(cur + 1, true);
        for (int x = cur + 1; x < n; ++x) {
            for (int a = 0; a < 2; ++a) {
                w[x][a] -= canbe[cur][curt][x][a];
            }
        }
        if (res) {
            return true;
        }
        break;
    }
    while (voc[ans[cur]] == curt && ans[cur] < l) {
        ++ans[cur];
    }
    if (ans[cur] == l) return false;

    curt = voc[ans[cur]];
    if (w[cur][curt] < cur) return false;
    for (int x = cur + 1; x < n; ++x) {
        for (int a = 0; a < 2; ++a) {
            w[x][a] += canbe[cur][curt][x][a];
        }
    }
    bool res = place(cur + 1, true);
    for (int x = cur + 1; x < n; ++x) {
        for (int a = 0; a < 2; ++a) {
            w[x][a] -= canbe[cur][curt][x][a];
        }
    }
    if (res) {
        return true;
    }

    return false;
}
int main() {
//    FREIN("in.txt");
    cin >> s;
    l = (int) s.size();
    FI(l) {
        voc[i] = (s[i] == 'V');
    }
    int m;
    cin >> n >> m;
    FI(m) {
        int x, y;
        char a, b;
        cin >> x >> a >> y >> b;
        --x; --y;
        a = (a == 'V');
        b = (b == 'V');
        v[x][a].push_back({y, b});
    }
    cin >> s;
    for (int i = 0; i < s.size(); ++i) {
        s[i] -= 'a';
    }
    for (int i = 0; i < n; ++i) {
        for (int k = 0; k < 2; ++k) {
            memset(used, 0, sizeof(used));
            sx = i;
            sa = k;
            go(i, k);
            bool b = false;
            for (int j = 0; j < n; ++j) {
                if (used[j][0] && used[j][1]) { b = true; break; }
                if (used[j][0] && isbad[j][0]) { b = true; break; }
                if (used[j][1] && isbad[j][1]) { b = true; break; }
            }
            if (b) {
                isbad[i][k] = true;
            }
        }
        if (isbad[i][0] && isbad[i][1]) {
            DIE();
        }

        ans[i] = s[i];
    }
    for (int x = 0; x < n; ++x) {
        for (int a = 0; a < 2; ++a) {
            if (isbad[x][a]) {
                continue;
            }
            for (int y = 0; y < n; ++y) {
                for (int b = 0; b < 2; ++b) {
                    if (isbad[y][b]) { continue;};
                    if (way[x][a][y][1 - b]) continue;
                    canbe[x][a][y][b] = true;
                    for (int z = 0; z < n; ++z) {
                        canbe[x][a][y][b] &= !((way[x][a][z][0] && way[y][b][z][1]) ||
                                              (way[x][a][z][1] && way[y][b][z][0]));
                    }
                }
            }
        }
        for (int y = 0; y < n; ++y) {
            int t = canbe[x][0][y][0] + canbe[x][1][y][0] + canbe[x][1][y][1] + canbe[x][0][y][1];
            if (t == 0) {
                DIE();
            }
        }
    }
//    for (int x = 0; x < n; ++x) {
//        for (int a = 0; a < 2; ++a) {
//            for (int y = 0; y < n; ++y) {
//                for (int b = 0; b < 2; ++b) {
//                    DBN(x, a, y, b, canbe[x][a][y][b]);
//                    DBN(x, a, y, b, way[x][a][y][b]);
//                }
//            }
//        }
//    }
//

    for (int i = 0; i < n; ++i) {
        if (i == -1) {
            DIE();
        }
        if (mustb[i]) {
            int curt = voc[ans[i]];
            bool ok = true;
            while (voc[ans[i]] == curt) {
                if (ans[i] == l) {
                    ok = false;
                    break;
                }
            }
        }
    }

    bool res = place(0);
    if (!res) {
        DIE();
    }
    if (iter > 200 * 25) {
        throw "LOL";
    }

    for (int i = 0; i < n; ++i) {
        s[i] = ans[i] + 'a';
    }
    cout << s << endl;
    return 0;
}

/*
VCCV
200 4
1 V 200 V
199 V 200 C
197 С 199 С
197 V 200 C
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

 */


#pragma comment(linker, "/stack:20000000")
#define _CRT_SECURE_NO_WARNINGS
# include <iostream>
# include <cmath>
# include <algorithm>
# include <cstdio>
# include <cstring>
# include <string>
# include <cstdlib>
# include <vector>
# include <bitset>
# include <map>
# include <queue>
# include <ctime>
# include <stack>
# include <set>
# include <list>
# include <deque>
# include <functional>
# include <sstream>
# include <fstream>
# include <complex>
# include <numeric>
using namespace std;

// Let's define unordered map
# ifdef __GNUC__
# if __cplusplus > 199711L
# include <unordered_map>
# else
# include <tr1/unordered_map>
using namespace std::tr1;
# endif
# else
# include <unordered_map>
# endif

#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL_((0,__VA_ARGS__, 5,4,3,2,1))
#define VA_NUM_ARGS_IMPL_(tuple) VA_NUM_ARGS_IMPL tuple
#define VA_NUM_ARGS_IMPL(_0,_1,_2,_3,_4,_5,N,...) N

#define macro_dispatcher(macro, ...) macro_dispatcher_(macro, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(macro, nargs) macro_dispatcher__(macro, nargs)
#define macro_dispatcher__(macro, nargs) macro_dispatcher___(macro, nargs)
#define macro_dispatcher___(macro, nargs) macro ## nargs

#define DBN1(a)			std::cerr<<#a<<"="<<(a)<<"\n"
#define DBN2(a,b)		std::cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<"\n"
#define DBN3(a,b,c)		std::cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<"\n"
#define DBN4(a,b,c,d)	std::cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<"\n"
#define DBN5(a,b,c,d,e)	std::cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<"\n"

#define DEB(x) std::cerr<<#x<<"="<<(x)<<"  "

#define DB(x) DEB(x)
#define DBN(...) macro_dispatcher(DBN, __VA_ARGS__)(__VA_ARGS__)
#define DA(a,n) cout<<#a<<"=["; printarray(a,n); cout<<"]\n"
#define DAR(a,n,s) cout<<#a<<"["<<s<<"-"<<n-1<<"]=["; printarray(a,n,s); cout<<"]\n"

double __begin;
#define DTIME(ccc) __begin = clock(); ccc; std::cerr<<"Time of work = "<<(clock()-__begin)/CLOCKS_PER_SEC<<std::endl;

#define mp make_pair
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<long long,long long> pll;
typedef vector<int> vi;
typedef vector<long long> vll;

template<typename T1,typename T2,typename T3>
struct triple{T1 a;T2 b;T3 c;triple(){};triple(T1 _a,T2 _b, T3 _c):a(_a),b(_b),c(_c){}};
#define tri triple<int,int,int>
#define trl triple<ll,ll,ll>
template<typename T1,typename T2,typename T3>
bool operator<(const triple<T1,T2,T3> &t1,const triple<T1,T2,T3> &t2){if (t1.a!=t2.a) return t1.a<t2.a; else if (t1.b != t2.b) return t1.b<t2.b; else return t1.c < t2.c; }
template<typename T1, typename T2, typename T3>
inline std::ostream& operator << (std::ostream& os, const triple<T1, T2, T3>& t){ return os << "(" << t.a << ", " << t.b << ", " << t.c << ")"; }

#define FI(n) for(int i=0;i<n;i++)
#define FJ(n) for(int j=0;j<n;j++)

//STL containers
#define foreach(v, c)               for( auto v = (c).begin();  v != (c).end(); ++v)
#define all(a)                      a.begin(), a.end()
#define in(a,b)                     ((b).find(a) != (b).end())
#define in2(a,b)                    (find(all(b),a) != (b).end())
#define sz(a)                       ((int)(a.size()))
#define svi(vec,n) FI(n) S(vec[y])
#define svl(vec,n) FI(n) Sl(vec[y])

//int some_primes[10] = {100271, 500179, 1000003, 2000227, 5000321}
//fill char arrays
#define fill(a,v)                    memset(a, v, sizeof (a))

inline int bits_count(int v){v=v-((v>>1)&0x55555555);v=(v&0x33333333)+((v>>2)&0x33333333);return((v+(v>>4)&0xF0F0F0F)*0x1010101)>>24;}
inline int bits_count(ll v){ int t = v >> 32; int p = (v & ((1LL << 32) - 1)); return bits_count(t) + bits_count(p); }
unsigned int reverse_bits(register unsigned int x){x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));return((x >> 16) | (x << 16));}
inline int sign(int x){return (x >> 31) | (-x >> 31);}
inline bool ispow2(int x){return (x!=0 && (x&(x-1))==0);}
#define checkbit(n,b)        ( (n >> b) & 1)
#define INDEX(arr,ind)       (lower_bound(all(arr),ind)-arr.begin())
#define sor(a)  sort(all(a))
#define rsor(a) sort(all(a)); reverse(all(a));

//STL output ********************************
template<typename T1,typename T2>inline std::ostream& operator << (std::ostream& os, const std::pair<T1, T2>& p){return os << "(" << p.first << ", " << p.second << ")";}
template<typename T>inline std::ostream &operator<<(std::ostream &os,const std::vector<T>& v){bool first=true;os<<"[";for(unsigned int i=0;i<v.size();i++){if(!first)os<<", ";os<<v[i];first=false;}return os<<"]";}
template<typename T>inline std::ostream &operator<<(std::ostream &os,const std::set<T>&v){bool first=true;os << "[";for(typename std::set<T>::const_iterator ii=v.begin();ii!=v.end();++ii){if(!first)os<<", ";os<<*ii;first=false;}return os<<"]";}
template<typename T1, typename T2>inline std::ostream &operator << (std::ostream & os,const std::map<T1, T2>& v){bool first = true; os << "[";for (typename std::map<T1,T2>::const_iterator ii =v.begin();ii!=v.end();++ii){if(!first)os<<", ";os<<*ii;first=false;}return os<<"]";}
template<typename T,typename T2>void printarray(T  a[],T2 sz,T2 beg=0){for(T2 i=beg;i<sz;i++) cout<<a[i]<<" ";cout<<endl;}

#define FREIN(FILE) freopen(FILE,"rt",stdin)
#define FREOUT(FILE) freopen(FILE,"wt",stdout)

#define sqr(x) ((x)*(x))
#define sqrt(x) sqrt(1.0*(x))
#define pow(x,n) pow(1.0*(x),n)

inline ll powmod(ll x,ll n, ll _mod){ll res=1;while(n){if(n&1)res=(res*x)%_mod;x=(x*x)%_mod;n>>=1;}return res;}
inline ll gcd(ll a,ll b){ll t;while(b){a=a%b;t=a;a=b;b=t;}return a;}
inline int gcd(int a,int b){int t;while(b){a=a%b;t=a;a=b;b=t;}return a;}
inline ll lcm(int a,int b){return a/gcd(a,b)*(ll)b;}
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll gcd(ll a,ll b,ll c){return gcd(gcd(a,b),c);}
inline int gcd(int a,int b,int c){return gcd(gcd(a,b),c);}
inline ll lcm(ll a,ll b,ll c){return lcm(lcm(a,b),c);}
inline ll lcm(int a,int b,int c){return lcm(lcm(a,b),(ll)c);}

inline ll max(ll a,ll b){return (a>b)?a:b;}
inline int max(int a,int b){return (a>b)?a:b;}
inline double max(double a,double b){return (a>b)?a:b;}
inline ll max(ll a,ll b,ll c){return max(a,max(b,c));}
inline int max(int a,int b,int c){return max(a,max(b,c));}
inline double max(double a,double b,double c){return max(a,max(b,c));}
inline ll min(ll a,ll b){return (a<b)?a:b;}
inline int min(int a,int b){return (a<b)?a:b;}
inline double min(double a,double b){return (a<b)?a:b;}
inline ll min(ll a,ll b,ll c){return min(a,min(b,c));}
inline int min(int a,int b,int c){return min(a,min(b,c));}
inline double min(double a,double b,double c){return min(a,min(b,c));}

template<class T>
inline void getar(T a, int n, int m){ for (int i = 0; i < n; i++) for (int j = 0; j < m;++j) { scanf("%d", &a[i][j]); } }
inline void getar(int *a, int n){ for (int ii = 0; ii < n; ii++){ scanf("%d", a + ii); } }
inline void getar(pii *a, int n){ for (int ii = 0; ii < n; ii++){ scanf("%d%d", &a[ii].first, &a[ii].second); } }
inline void getar(ll *a, int n){ for (int ii = 0; ii < n; ii++){ scanf("%I64d", a + ii); } }
template<class T>
inline void cinarr(T &a, int n){ for (int i=0;i<n;++i) cin >> a[i];}
// Useful constants

#define INF			1011111111
#define EPS			(double)1e-15
#define mod			1000000007
#define PI			3.14159265358979323
//*******************************************************************************/

bool voc[10010];
vector<pii> v[201][2];
bool isbad[201][2];
bool used[201][2];
int w[201][2];
bool way[201][2][201][2];
bool canbe[201][2][201][2];
bool isb = false;
bool wentb[201];
bool mustb[201];
int sx, sa;
void go(int x, int a) {
    used[x][a] = true;
    way[sx][sa][x][a] = true;
    for (auto to : v[x][a]) {
        if (!used[to.first][to.second]) {
            go(to.first, to.second);
        }
    }
}
void DIE() {
    cout << -1 << endl;
    exit(0);
}
string s;
int n;
int l;
int ans[202];
int iter = 0;
bool place(int cur, bool can = false) {
    ++iter;
    if (cur == n) return true;
    for (int i = cur; i < n; ++i) {
        int t = (w[i][0] == cur) + (w[i][1] == cur);
        if (t == 0) return false;
    }
    if (can) {
        ans[cur] = 0;
    } else {
        ans[cur] = s[cur];
    }
    int curt = voc[ans[cur]];
    if (w[cur][curt] == cur) {
        for (int x = cur + 1; x < n; ++x) {
            for (int a = 0; a < 2; ++a) {
                w[x][a] += canbe[cur][curt][x][a];
            }
        }
        bool res = place(cur + 1, can);
        for (int x = cur + 1; x < n; ++x) {
            for (int a = 0; a < 2; ++a) {
                w[x][a] -= canbe[cur][curt][x][a];
            }
        }
        if (res) {
            return true;
        }
    }
    ++ans[cur];
    if (ans[cur] == l) return false;
    while(can == false)
    {
        curt = voc[ans[cur]];
        if (w[cur][curt] < cur) break;
        for (int x = cur + 1; x < n; ++x) {
            for (int a = 0; a < 2; ++a) {
                w[x][a] += canbe[cur][curt][x][a];
            }
        }
        bool res = place(cur + 1, true);
        for (int x = cur + 1; x < n; ++x) {
            for (int a = 0; a < 2; ++a) {
                w[x][a] -= canbe[cur][curt][x][a];
            }
        }
        if (res) {
            return true;
        }
        break;
    }
    while (voc[ans[cur]] == curt && ans[cur] < l) {
        ++ans[cur];
    }
    if (ans[cur] == l) return false;

    curt = voc[ans[cur]];
    if (w[cur][curt] < cur) return false;
    for (int x = cur + 1; x < n; ++x) {
        for (int a = 0; a < 2; ++a) {
            w[x][a] += canbe[cur][curt][x][a];
        }
    }
    bool res = place(cur + 1, true);
    for (int x = cur + 1; x < n; ++x) {
        for (int a = 0; a < 2; ++a) {
            w[x][a] -= canbe[cur][curt][x][a];
        }
    }
    if (res) {
        return true;
    }

    return false;
}
int main() {
//    FREIN("in.txt");
    cin >> s;
    l = (int) s.size();
    FI(l) {
        voc[i] = (s[i] == 'V');
    }
    int m;
    cin >> n >> m;
    FI(m) {
        int x, y;
        char a, b;
        cin >> x >> a >> y >> b;
        --x; --y;
        a = (a == 'V');
        b = (b == 'V');
        v[x][a].push_back({y, b});
    }
    cin >> s;
    for (int i = 0; i < s.size(); ++i) {
        s[i] -= 'a';
    }
    for (int i = 0; i < n; ++i) {
        for (int k = 0; k < 2; ++k) {
            memset(used, 0, sizeof(used));
            sx = i;
            sa = k;
            go(i, k);
            bool b = false;
            for (int j = 0; j < n; ++j) {
                if (used[j][0] && used[j][1]) { b = true; break; }
                if (used[j][0] && isbad[j][0]) { b = true; break; }
                if (used[j][1] && isbad[j][1]) { b = true; break; }
            }
            if (b) {
                isbad[i][k] = true;
            }
        }
        if (isbad[i][0] && isbad[i][1]) {
            DIE();
        }

        ans[i] = s[i];
    }
    for (int x = 0; x < n; ++x) {
        for (int a = 0; a < 2; ++a) {
            if (isbad[x][a]) {
                continue;
            }
            for (int y = 0; y < n; ++y) {
                for (int b = 0; b < 2; ++b) {
                    if (isbad[y][b]) { continue;};
                    if (way[x][a][y][1 - b]) continue;
                    canbe[x][a][y][b] = true;
                    for (int z = 0; z < n; ++z) {
                        canbe[x][a][y][b] &= !((way[x][a][z][0] && way[y][b][z][1]) ||
                                              (way[x][a][z][1] && way[y][b][z][0]));
                    }
                }
            }
        }
        for (int y = 0; y < n; ++y) {
            int t = canbe[x][0][y][0] + canbe[x][1][y][0] + canbe[x][1][y][1] + canbe[x][0][y][1];
            if (t == 0) {
                DIE();
            }
        }
    }
//    for (int x = 0; x < n; ++x) {
//        for (int a = 0; a < 2; ++a) {
//            for (int y = 0; y < n; ++y) {
//                for (int b = 0; b < 2; ++b) {
//                    DBN(x, a, y, b, canbe[x][a][y][b]);
//                    DBN(x, a, y, b, way[x][a][y][b]);
//                }
//            }
//        }
//    }
//

    for (int i = 0; i < n; ++i) {
        if (i == -1) {
            DIE();
        }
        if (mustb[i]) {
            int curt = voc[ans[i]];
            bool ok = true;
            while (voc[ans[i]] == curt) {
                if (ans[i] == l) {
                    ok = false;
                    break;
                }
            }
        }
    }

    bool res = place(0);
    if (!res) {
        DIE();
    }
    if (iter > 210) {
        throw "LOL";
    }

    for (int i = 0; i < n; ++i) {
        s[i] = ans[i] + 'a';
    }
    cout << s << endl;
    return 0;
}

/*
VCCV
200 4
1 V 200 V
199 V 200 C
197 С 199 С
197 V 200 C
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

 */


//指定小写字母元音/辅音
//给出第i个位置是元音/辅音蕴涵j位置元音/辅音
//给定字符串st,求字典序不小于它的最小的合法2-sat方案
#include <bits/stdc++.h>
#define MAXN 500
#define MAXM 512345

using namespace std;
typedef int arrayN[MAXN], arrayM[MAXM];

char g[30], st[MAXN];
arrayN fir0, low, dfn, inVec, cnt, belong;
arrayN deg, con0, con1, fir1, topOrder, col;
arrayM e0, nxt0, e1, nxt1;
int num, now, tot, nextAlp[30][2], firAlp[2];
vector<int> vec;

int getKind(char ch) {
    if (ch == 'V') return 0;
    else return 1;
}

void link0(int u, int v) {
    e0[++num] = v, nxt0[num] = fir0[u];
    fir0[u] = num;
}

void link1(int u, int v) {
    e1[++num] = v, nxt1[num] = fir1[u];
    fir1[u] = num;
}

void tarjan(int x) {
    low[x] = dfn[x] = ++now;
    vec.push_back(x);
    for (int p = fir0[x], q; p; p = nxt0[p])
        if (!inVec[q = e0[p]])
            if (!dfn[e0[p]]) {
                tarjan(e0[p]);
                low[x] = min(low[x], low[e0[p]]);
            } else low[x] = min(low[x], dfn[e0[p]]);
    if (low[x] == dfn[x]) {
        cnt[belong[x] = ++tot] = 1;
        inVec[x] = 1;
        for (; vec.back() != x; vec.pop_back()) {
            int q = vec.back();
            inVec[q] = 1;
            cnt[belong[q] = tot]++;
        }
        vec.pop_back();
    }
}

void topSort() {
    int l = 1, r = 0;
    for (int i = 1; i <= tot; ++i)
        if (deg[i] == 0) topOrder[++r] = i;
    for (; l <= r; ++l) {
        int u = topOrder[l];
        for (int p = fir1[u]; p; p = nxt1[p]) {
            --deg[e1[p]];
            if (deg[e1[p]] == 0) topOrder[++r] = e1[p];
        }
    }
}
int getDAG(int n) {
    for (int i = 1; i <= n * 2; ++i)
        dfn[i] = low[i] = belong[i] = inVec[i] = deg[i] = 0;
    now = tot = num = 0;
    for (int i = 1; i <= n * 2; ++i)
        if (!dfn[i]) tarjan(i);
    for (int i = 1; i <= n; ++i)
        if (belong[i] == belong[con0[i]]) return 0;
    for (int i = 1; i <= 2 * n; ++i) {
        for (int p = fir0[i]; p; p = nxt0[p]) {
            int q = e0[p];
            if (belong[i] == belong[q]) continue;
            link1(belong[q], belong[i]);
            deg[belong[i]]++;
        }
        con1[belong[i]] = belong[con0[i]];
        con1[belong[con0[i]]] = belong[i];
    }
    topSort();
    return 1;
}

int dye(int x, int co) {
    if (col[x]) {
        return (co == col[x]);
    }
    col[x] = co;
    for (int p = fir1[x]; p; p = nxt1[p])
        if (!dye(e1[p], co)) return 0;
    return 1;
}

int originDye(int p) {
    for (int i = 1; i <= p + 1; ++i) {
        int pos = belong[i];
        if (getKind(g[st[i - 1] - 'a'])) pos = con1[pos];
        if (col[pos] == 2) return 0;
        col[pos] = 1;
        if (!dye(con1[pos], 2)) return 0;
    }
    return 1;
}
int DAGDye(int n) {
    for (int i = 1; i <= n; ++i) {
        int x = topOrder[i];
        if (!col[x]) {
            col[x] = 1;
            if (!dye(con1[x], 2)) return 0;
        }
    }
    return 1;
}

int finalCheck(int n, int p) {
    for (int i = 1; i <= n; ++i) {
        if (col[belong[i]] != 1 && col[belong[con0[i]]] != 1) return 0;
    }
    return 1;
}

int solve(int n, int p) {
    memset(col, 0, sizeof(col));
    if (!originDye(p)) return 0;
    if (!DAGDye(tot)) return 0;
    return finalCheck(n, p);
}

void getNextAlp() {
    int len = strlen(g);
    firAlp[1] = firAlp[0] = 'z' + 1;
    for (int i = 0; i < len; ++i) {
        nextAlp[i][0] = nextAlp[i][1] = 'z' + 1;
        int k = getKind(g[i]);
        firAlp[k] = min(firAlp[k], i + 'a');
        for (int j = i + 1; j < len; ++j) {
            int k = getKind(g[j]);
            nextAlp[i][k] = min(nextAlp[i][k], 'a' + j);
        }
        if (nextAlp[i][0] > nextAlp[i][1])
            swap(nextAlp[i][0], nextAlp[i][1]);
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    scanf("%s", g);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        con0[i] = i + n;
        con0[i + n] = i;
    }
    num = 0;
    for (int i = 1; i <= m; ++i) {
        char t1, t2;
        int pos1, pos2;
        scanf("%d %c %d %c\n", &pos1, &t1, &pos2, &t2);
        if (i == 50) printf("%d %c %d %c\n", pos1, t1, pos2, t2);
        int k1 = getKind(t1);
        int k2 = getKind(t2);
        pos1 += k1 * n;
        pos2 += k2 * n;
        link0(pos1, pos2);
        link0(con0[pos2], con0[pos1]);
    }
    scanf("%s", st);
    printf("%s\n", st);
    getNextAlp();
    if (getDAG(n) == 0) {
        printf("-1\n");
        return 0;
    }
    int flag = solve(n, n - 1);
    for (int i = n - 1; i >= 0 && !flag; --i) {
        for (int j = 0; j <= 1 && !flag; ++j)
            if (nextAlp[st[i] - 'a'][j] <= 'z') {
                st[i] = nextAlp[st[i] - 'a'][j];
                flag = solve(n, i);
                if (flag) {
                    for (int k = i + 1; k <= n - 1; ++k) {
                        int u = firAlp[0];
                        int v = firAlp[1];
                        if (u > v) swap(u, v);
                        st[k] = u;
                        if (solve(n, k)) continue;
                        st[k] = v;
                    }
                }
            }
    }
    if (!flag) printf("-1\n");
    else printf("%s\n", st);
    return 0;
}


//指定小写字母元音/辅音
//给出第i个位置是元音/辅音蕴涵j位置元音/辅音
//给定字符串st,求字典序不小于它的最小的合法2-sat方案
#include <bits/stdc++.h>
#define MAXN 500
#define MAXM 512345

using namespace std;
typedef int arrayN[MAXN], arrayM[MAXM];

char g[30], st[MAXN];
arrayN fir0, low, dfn, inVec, cnt, belong;
arrayN deg, con0, con1, fir1, topOrder, col;
arrayM e0, nxt0, e1, nxt1;
int num, now, tot, nextAlp[30][2], firAlp[2];
vector<int> vec;

int getKind(char ch) {
    if (ch == 'V') return 0;
    else return 1;
}

void link0(int u, int v) {
    e0[++num] = v, nxt0[num] = fir0[u];
    fir0[u] = num;
}

void link1(int u, int v) {
    e1[++num] = v, nxt1[num] = fir1[u];
    fir1[u] = num;
}

void tarjan(int x) {
    low[x] = dfn[x] = ++now;
    vec.push_back(x);
    for (int p = fir0[x], q; p; p = nxt0[p])
        if (!inVec[q = e0[p]])
            if (!dfn[e0[p]]) {
                tarjan(e0[p]);
                low[x] = min(low[x], low[e0[p]]);
            } else low[x] = min(low[x], dfn[e0[p]]);
    if (low[x] == dfn[x]) {
        cnt[belong[x] = ++tot] = 1;
        inVec[x] = 1;
        for (; vec.back() != x; vec.pop_back()) {
            int q = vec.back();
            inVec[q] = 1;
            cnt[belong[q] = tot]++;
        }
        vec.pop_back();
    }
}

void topSort() {
    int l = 1, r = 0;
    for (int i = 1; i <= tot; ++i)
        if (deg[i] == 0) topOrder[++r] = i;
    for (; l <= r; ++l) {
        int u = topOrder[l];
        for (int p = fir1[u]; p; p = nxt1[p]) {
            --deg[e1[p]];
            if (deg[e1[p]] == 0) topOrder[++r] = e1[p];
        }
    }
}
int getDAG(int n) {
    for (int i = 1; i <= n * 2; ++i)
        dfn[i] = low[i] = belong[i] = inVec[i] = deg[i] = 0;
    now = tot = num = 0;
    for (int i = 1; i <= n * 2; ++i)
        if (!dfn[i]) tarjan(i);
    for (int i = 1; i <= n; ++i)
        if (belong[i] == belong[con0[i]]) return 0;
    for (int i = 1; i <= 2 * n; ++i) {
        for (int p = fir0[i]; p; p = nxt0[p]) {
            int q = e0[p];
            if (belong[i] == belong[q]) continue;
            link1(belong[q], belong[i]);
            deg[belong[i]]++;
        }
        con1[belong[i]] = belong[con0[i]];
        con1[belong[con0[i]]] = belong[i];
    }
    topSort();
    return 1;
}

int dye(int x, int co) {
    if (col[x]) {
        return (co == col[x]);
    }
    col[x] = co;
    for (int p = fir1[x]; p; p = nxt1[p])
        if (!dye(e1[p], co)) return 0;
    return 1;
}

int originDye(int p) {
    for (int i = 1; i <= p + 1; ++i) {
        int pos = belong[i];
        if (getKind(g[st[i - 1] - 'a'])) pos = con1[pos];
        if (col[pos] == 2) return 0;
        col[pos] = 1;
        if (!dye(con1[pos], 2)) return 0;
    }
    return 1;
}
int DAGDye(int n) {
    for (int i = 1; i <= n; ++i) {
        int x = topOrder[i];
        if (!col[x]) {
            col[x] = 1;
            if (!dye(con1[x], 2)) return 0;
        }
    }
    return 1;
}

int finalCheck(int n, int p) {

    for (int i = 1; i <= n; ++i) {
        if (col[belong[i]] != 1 && col[belong[con0[i]]] != 1) return 0;
    }
    return 1;
}

int solve(int n, int p) {
    memset(col, 0, sizeof(col));
    if (!originDye(p)) return 0;
    if (!DAGDye(tot)) return 0;
    return finalCheck(n, p);
}

void getNextAlp() {
    int len = strlen(g);
    firAlp[1] = firAlp[0] = 'z' + 1;
    for (int i = 0; i < len; ++i) {
        nextAlp[i][0] = nextAlp[i][1] = 'z' + 1;
        int k = getKind(g[i]);
        firAlp[k] = min(firAlp[k], i + 'a');
        for (int j = i + 1; j < len; ++j) {
            int k = getKind(g[j]);
            nextAlp[i][k] = min(nextAlp[i][k], 'a' + j);
        }
        if (nextAlp[i][0] > nextAlp[i][1])
            swap(nextAlp[i][0], nextAlp[i][1]);
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    scanf("%s", g);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        con0[i] = i + n;
        con0[i + n] = i;
    }
    num = 0;
    for (int i = 1; i <= m; ++i) {
        char t1, t2;
        int pos1, pos2;
        scanf("%d %c %d %c\n", &pos1, &t1, &pos2, &t2);
        int k1 = getKind(t1);
        int k2 = getKind(t2);
        pos1 += k1 * n;
        pos2 += k2 * n;
        link0(pos1, pos2);
        link0(con0[pos2], con0[pos1]);
    }
    scanf("%s", st);
    getNextAlp();
    if (getDAG(n) == 0) {
        printf("-1\n");
        return 0;
    }
    int flag = solve(n, n - 1);
    for (int i = n - 1; i >= 0 && !flag; --i) {
        for (int j = 0; j <= 1 && !flag; ++j)
            if (nextAlp[st[i] - 'a'][j] <= 'z') {
                st[i] = nextAlp[st[i] - 'a'][j];
                flag = solve(n, i);
                if (flag) {
                    for (int k = i + 1; k <= n - 1; ++k) {
                        int u = firAlp[0];
                        int v = firAlp[1];
                        if (u > v) swap(u, v);
                        st[k] = u;
                        if (solve(n, k)) continue;
                        st[k] = v;
                    }
                }
            }
    }
    if (!flag) printf("-1\n");
    else printf("%s\n", st);
    return 0;
}


//指定小写字母元音/辅音
//给出第i个位置是元音/辅音蕴涵j位置元音/辅音
//给定字符串st,求字典序不小于它的最小的合法2-sat方案
#include <bits/stdc++.h>
#define MAXN 500
#define MAXM 512345

using namespace std;
typedef int arrayN[MAXN], arrayM[MAXM];

char g[30], st[MAXN];
arrayN fir0, low, dfn, inVec, cnt, belong;
arrayN deg, con0, con1, fir1, topOrder, col;
arrayM e0, nxt0, e1, nxt1;
int num, now, tot, nextAlp[30][2], firAlp[2];
vector<int> vec;

int getKind(char ch) {
    if (ch == 'V') return 0;
    else return 1;
}

void link0(int u, int v) {
    e0[++num] = v, nxt0[num] = fir0[u];
    fir0[u] = num;
}

void link1(int u, int v) {
    e1[++num] = v, nxt1[num] = fir1[u];
    fir1[u] = num;
}

void tarjan(int x) {
    low[x] = dfn[x] = ++now;
    vec.push_back(x);
    for (int p = fir0[x], q; p; p = nxt0[p])
        if (!inVec[q = e0[p]])
            if (!dfn[e0[p]]) {
                tarjan(e0[p]);
                low[x] = min(low[x], low[e0[p]]);
            } else low[x] = min(low[x], dfn[e0[p]]);
    if (low[x] == dfn[x]) {
        cnt[belong[x] = ++tot] = 1;
        inVec[x] = 1;
        for (; vec.back() != x; vec.pop_back()) {
            int q = vec.back();
            inVec[q] = 1;
            cnt[belong[q] = tot]++;
        }
        vec.pop_back();
    }
}

void topSort() {
    int l = 1, r = 0;
    for (int i = 1; i <= tot; ++i)
        if (deg[i] == 0) topOrder[++r] = i;
    for (; l <= r; ++l) {
        int u = topOrder[l];
        for (int p = fir1[u]; p; p = nxt1[p]) {
            --deg[e1[p]];
            if (deg[e1[p]] == 0) topOrder[++r] = e1[p];
        }
    }
}
int getDAG(int n) {
    for (int i = 1; i <= n * 2; ++i)
        dfn[i] = low[i] = belong[i] = inVec[i] = deg[i] = 0;
    now = tot = num = 0;
    for (int i = 1; i <= n * 2; ++i)
        if (!dfn[i]) tarjan(i);
    for (int i = 1; i <= n; ++i)
        if (belong[i] == belong[con0[i]]) return 0;
    for (int i = 1; i <= 2 * n; ++i) {
        for (int p = fir0[i]; p; p = nxt0[p]) {
            int q = e0[p];
            if (belong[i] == belong[q]) continue;
            link1(belong[q], belong[i]);
            deg[belong[i]]++;
        }
        con1[belong[i]] = belong[con0[i]];
        con1[belong[con0[i]]] = belong[i];
    }
    topSort();
    return 1;
}

int dye(int x, int co) {
    if (col[x]) {
        return (co == col[x]);
    }
    col[x] = co;
    for (int p = fir1[x]; p; p = nxt1[p])
        if (!dye(e1[p], co)) return 0;
    return 1;
}

int originDye(int p) {
    for (int i = 1; i <= p + 1; ++i) {
        int pos = belong[i];
        if (getKind(g[st[i - 1] - 'a'])) pos = con1[pos];
        if (col[pos] == 2) return 0;
        col[pos] = 1;
        if (!dye(con1[pos], 2)) return 0;
    }
    return 1;
}
int DAGDye(int n) {
    for (int i = 1; i <= n; ++i) {
        int x = topOrder[i];
        if (!col[x]) {
            col[x] = 1;
            if (!dye(con1[x], 2)) return 0;
        }
    }
    return 1;
}

int finalCheck(int n, int p) {
    for (int i = 1; i <= n; ++i) {
        if (col[belong[i]] != 1 && col[belong[con0[i]]] != 1) return 0;
    }
    return 1;
}

int solve(int n, int p) {
    memset(col, 0, sizeof(col));
    if (!originDye(p)) return 0;
    if (!DAGDye(tot)) return 0;
    return finalCheck(n, p);
}

void getNextAlp() {
    int len = strlen(g);
    firAlp[1] = firAlp[0] = 'z' + 1;
    for (int i = 0; i < len; ++i) {
        nextAlp[i][0] = nextAlp[i][1] = 'z' + 1;
        int k = getKind(g[i]);
        firAlp[k] = min(firAlp[k], i + 'a');
        for (int j = i + 1; j < len; ++j) {
            int k = getKind(g[j]);
            nextAlp[i][k] = min(nextAlp[i][k], 'a' + j);
        }
        if (nextAlp[i][0] > nextAlp[i][1])
            swap(nextAlp[i][0], nextAlp[i][1]);
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    scanf("%s", g);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        con0[i] = i + n;
        con0[i + n] = i;
    }
    num = 0;
    for (int i = 1; i <= m; ++i) {
        char t1, t2;
        int pos1, pos2;
        scanf("%d %c %d %c\n", &pos1, &t1, &pos2, &t2);
        if (i == 50 && n == 50 && m == 50) printf("%d %c %d %c\n", pos1, t1, pos2, t2);
        int k1 = getKind(t1);
        int k2 = getKind(t2);
        pos1 += k1 * n;
        pos2 += k2 * n;
        link0(pos1, pos2);
        link0(con0[pos2], con0[pos1]);
    }
    scanf("%s", st);
    if (n == 50 && m == 50) printf("%s\n", st);
    getNextAlp();
    if (getDAG(n) == 0) {
        printf("-1\n");
        return 0;
    }
    int flag = solve(n, n - 1);
    for (int i = n - 1; i >= 0 && !flag; --i) {
        for (int j = 0; j <= 1 && !flag; ++j)
            if (nextAlp[st[i] - 'a'][j] <= 'z') {
                st[i] = nextAlp[st[i] - 'a'][j];
                flag = solve(n, i);
                if (flag) {
                    for (int k = i + 1; k <= n - 1; ++k) {
                        int u = firAlp[0];
                        int v = firAlp[1];
                        if (u > v) swap(u, v);
                        st[k] = u;
                        if (solve(n, k)) continue;
                        st[k] = v;
                    }
                }
            }
    }
    if (!flag) printf("-1\n");
    else printf("%s\n", st);
    return 0;
}


//指定小写字母元音/辅音
//给出第i个位置是元音/辅音蕴涵j位置元音/辅音
//给定字符串st,求字典序不小于它的最小的合法2-sat方案
#include <bits/stdc++.h>
#define MAXN 500
#define MAXM 512345

using namespace std;
typedef int arrayN[MAXN], arrayM[MAXM];

char g[30], st[MAXN];
arrayN fir0, low, dfn, inVec, cnt, belong;
arrayN deg, con0, con1, fir1, topOrder, col;
arrayM e0, nxt0, e1, nxt1;
int num, now, tot, nextAlp[30][2], firAlp[2];
vector<int> vec;

int getKind(char ch) {
    if (ch == 'V') return 0;
    else return 1;
}

void link0(int u, int v) {
    e0[++num] = v, nxt0[num] = fir0[u];
    fir0[u] = num;
}

void link1(int u, int v) {
    e1[++num] = v, nxt1[num] = fir1[u];
    fir1[u] = num;
}

void tarjan(int x) {
    low[x] = dfn[x] = ++now;
    vec.push_back(x);
    for (int p = fir0[x], q; p; p = nxt0[p])
        if (!inVec[q = e0[p]])
            if (!dfn[e0[p]]) {
                tarjan(e0[p]);
                low[x] = min(low[x], low[e0[p]]);
            } else low[x] = min(low[x], dfn[e0[p]]);
    if (low[x] == dfn[x]) {
        cnt[belong[x] = ++tot] = 1;
        inVec[x] = 1;
        for (; vec.back() != x; vec.pop_back()) {
            int q = vec.back();
            inVec[q] = 1;
            cnt[belong[q] = tot]++;
        }
        vec.pop_back();
    }
}

void topSort() {
    int l = 1, r = 0;
    for (int i = 1; i <= tot; ++i)
        if (deg[i] == 0) topOrder[++r] = i;
    for (; l <= r; ++l) {
        int u = topOrder[l];
        for (int p = fir1[u]; p; p = nxt1[p]) {
            --deg[e1[p]];
            if (deg[e1[p]] == 0) topOrder[++r] = e1[p];
        }
    }
}
int getDAG(int n) {
    for (int i = 1; i <= n * 2; ++i)
        dfn[i] = low[i] = belong[i] = inVec[i] = deg[i] = 0;
    now = tot = num = 0;
    for (int i = 1; i <= n * 2; ++i)
        if (!dfn[i]) tarjan(i);
    for (int i = 1; i <= n; ++i)
        if (belong[i] == belong[con0[i]]) return 0;
    for (int i = 1; i <= 2 * n; ++i) {
        for (int p = fir0[i]; p; p = nxt0[p]) {
            int q = e0[p];
            if (belong[i] == belong[q]) continue;
            link1(belong[q], belong[i]);
            deg[belong[i]]++;
        }
        con1[belong[i]] = belong[con0[i]];
        con1[belong[con0[i]]] = belong[i];
    }
    topSort();
    return 1;
}

int dye(int x, int co) {
    if (col[x]) {
        return (co == col[x]);
    }
    col[x] = co;
    for (int p = fir1[x]; p; p = nxt1[p])
        if (!dye(e1[p], co)) return 0;
    return 1;
}

int originDye(int p) {
    for (int i = 1; i <= p + 1; ++i) {
        int pos = belong[i];
        if (getKind(g[st[i - 1] - 'a'])) pos = con1[pos];
        if (col[pos] == 2) return 0;
        col[pos] = 1;
        if (!dye(con1[pos], 2)) return 0;
    }
    return 1;
}
int DAGDye(int n) {
    for (int i = 1; i <= n; ++i) {
        int x = topOrder[i];
        if (!col[x]) {
            col[x] = 1;
            if (!dye(con1[x], 2)) return 0;
        }
    }
    return 1;
}

int prtAns(int n, int p) {

    for (int i = 1; i <= n; ++i) {
        if (col[belong[i]] != 1 && col[belong[con0[i]]] != 1) return 0;
    }
    for (int i = 0; i <= p; ++i)
        printf("%c", st[i]);
    for (int i = p + 2; i <= n; ++i)
        if (col[belong[i]] == 1) printf("%c", firAlp[0]);
        else printf("%c", firAlp[1]);
    printf("\n");
    return 1;
}
int solve(int n, int p) {
    memset(col, 0, sizeof(col));
    if (!originDye(p)) return 0;
    if (!DAGDye(tot)) return 0;
    return prtAns(n, p);
}

void getNextAlp() {
    int len = strlen(g);
    firAlp[1] = firAlp[0] = 'z' + 1;
    for (int i = 0; i < len; ++i) {
        nextAlp[i][0] = nextAlp[i][1] = 'z' + 1;
        int k = getKind(g[i]);
        firAlp[k] = min(firAlp[k], i + 'a');
        for (int j = i + 1; j < len; ++j) {
            int k = getKind(g[j]);
            nextAlp[i][k] = min(nextAlp[i][k], 'a' + j);
        }
        if (nextAlp[i][0] > nextAlp[i][1])
            swap(nextAlp[i][0], nextAlp[i][1]);
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    scanf("%s", g);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        con0[i] = i + n;
        con0[i + n] = i;
    }
    num = 0;
    for (int i = 1; i <= m; ++i) {
        char t1, t2;
        int pos1, pos2;
        scanf("%d %c %d %c\n", &pos1, &t1, &pos2, &t2);
        int k1 = getKind(t1);
        int k2 = getKind(t2);
        pos1 += k1 * n;
        pos2 += k2 * n;
        link0(pos1, pos2);
        link0(con0[pos2], con0[pos1]);
    }
    scanf("%s", st);
    getNextAlp();
    if (getDAG(n) == 0) {
        printf("-1\n");
        return 0;
    }
    int flag = solve(n, n - 1);
    for (int i = n - 1; i >= 0 && !flag; --i) {
        for (int j = 0; j <= 1 && !flag; ++j)
            if (nextAlp[st[i] - 'a'][j] <= 'z') {
                st[i] = nextAlp[st[i] - 'a'][j];
                flag = solve(n, i);
            }
    }
    if (!flag) printf("-1\n");
    return 0;
}


//指定小写字母元音/辅音
//给出第i个位置是元音/辅音蕴涵j位置元音/辅音
//给定字符串st,求字典序不小于它的最小的合法2-sat方案
#include <bits/stdc++.h>
#define MAXN 500
#define MAXM 512345

using namespace std;
typedef int arrayN[MAXN], arrayM[MAXM];

char g[30], st[MAXN];
arrayN fir0, low, dfn, inVec, cnt, belong;
arrayN deg, con0, con1, fir1, topOrder, col;
arrayM e0, nxt0, e1, nxt1;
int num, now, tot, nextAlp[30][2], firAlp[2];
vector<int> vec;

int getKind(char ch) {
    if (ch == 'V') return 0;
    else return 1;
}

void link0(int u, int v) {
    e0[++num] = v, nxt0[num] = fir0[u];
    fir0[u] = num;
}

void link1(int u, int v) {
    e1[++num] = v, nxt1[num] = fir1[u];
    fir1[u] = num;
}

void tarjan(int x) {
    low[x] = dfn[x] = ++now;
    vec.push_back(x);
    for (int p = fir0[x], q; p; p = nxt0[p])
        if (!inVec[q = e0[p]])
            if (!dfn[e0[p]]) {
                tarjan(e0[p]);
                low[x] = min(low[x], low[e0[p]]);
            } else low[x] = min(low[x], dfn[e0[p]]);
    if (low[x] == dfn[x]) {
        cnt[belong[x] = ++tot] = 1;
        inVec[x] = 1;
        for (; vec.back() != x; vec.pop_back()) {
            int q = vec.back();
            inVec[q] = 1;
            cnt[belong[q] = tot]++;
        }
        vec.pop_back();
    }
}

void topSort() {
    int l = 1, r = 0;
    for (int i = 1; i <= tot; ++i)
        if (deg[i] == 0) topOrder[++r] = i;
    for (; l <= r; ++l) {
        int u = topOrder[l];
        for (int p = fir1[u]; p; p = nxt1[p]) {
            --deg[e1[p]];
            if (deg[e1[p]] == 0) topOrder[++r] = e1[p];
        }
    }
}
int getDAG(int n) {
    for (int i = 1; i <= n * 2; ++i)
        dfn[i] = low[i] = belong[i] = inVec[i] = deg[i] = 0;
    now = tot = num = 0;
    for (int i = 1; i <= n * 2; ++i)
        if (!dfn[i]) tarjan(i);
    for (int i = 1; i <= n; ++i)
        if (belong[i] == belong[con0[i]]) return 0;
    for (int i = 1; i <= 2 * n; ++i) {
        for (int p = fir0[i]; p; p = nxt0[p]) {
            int q = e0[p];
            if (belong[i] == belong[q]) continue;
            link1(belong[q], belong[i]);
            deg[belong[i]]++;
        }
        con1[belong[i]] = belong[con0[i]];
        con1[belong[con0[i]]] = belong[i];
    }
    topSort();
    return 1;
}

int dye(int x, int co) {
    if (col[x]) {
        return (co == col[x]);
    }
    col[x] = co;
    for (int p = fir1[x]; p; p = nxt1[p])
        if (!dye(e1[p], co)) return 0;
    return 1;
}

int originDye(int p) {
    for (int i = 1; i <= p + 1; ++i) {
        int pos = belong[i];
        if (getKind(g[st[i - 1] - 'a'])) pos = con1[pos];
        if (col[pos] == 2) return 0;
        col[pos] = 1;
        if (!dye(con1[pos], 2)) return 0;
    }
    return 1;
}
int DAGDye(int n) {
    for (int i = 1; i <= n; ++i) {
        int x = topOrder[i];
        if (!col[x]) {
            col[x] = 1;
            if (!dye(con1[x], 2)) return 0;
        }
    }
    return 1;
}

int prtAns(int n, int p) {

    for (int i = 1; i <= n; ++i) {
        if (col[belong[i]] != 1 && col[belong[con0[i]]] != 1) return 0;
    }
    for (int i = 0; i <= p; ++i)
        printf("%c", st[i]);
    for (int i = p + 2; i <= n; ++i)
        if (col[belong[i]] == 1) printf("%c", firAlp[0]);
        else printf("%c", firAlp[1]);
    printf("\n");
    return 1;
}
int solve(int n, int p) {
    memset(col, 0, sizeof(col));
    if (!originDye(p)) return 0;
    if (!DAGDye(tot)) return 0;
    return prtAns(n, p);
}

void getNextAlp() {
    int len = strlen(g);
    firAlp[1] = firAlp[0] = 'z' + 1;
    for (int i = 0; i < len; ++i) {
        nextAlp[i][0] = nextAlp[i][1] = 'z' + 1;
        int k = getKind(g[st[i] - 'a']);
        firAlp[k] = min(firAlp[k], i + 'a');
        for (int j = i + 1; j < len; ++j) {
            int k = getKind(g[st[j] - 'a']);
            nextAlp[i][k] = min(nextAlp[i][k], 'a' + j);
        }
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    scanf("%s", g);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        con0[i] = i + n;
        con0[i + n] = i;
    }
    num = 0;
    for (int i = 1; i <= m; ++i) {
        char t1, t2;
        int pos1, pos2;
        scanf("%d %c %d %c\n", &pos1, &t1, &pos2, &t2);
        int k1 = getKind(t1);
        int k2 = getKind(t2);
        pos1 += k1 * n;
        pos2 += k2 * n;
        link0(pos1, pos2);
        link0(con0[pos2], con0[pos1]);
    }
    scanf("%s", st);
    getNextAlp();
    if (getDAG(n) == 0) {
        printf("-1\n");
        return 0;
    }
    int flag = solve(n, n - 1);
    for (int i = n - 1; i >= 0 && !flag; --i) {
        for (int j = 0; j <= 1 && !flag; ++j)
            if (nextAlp[st[i] - 'a'][j] <= 'z') {
                st[i] = nextAlp[st[i] - 'a'][j];
                flag = solve(n, i);
            }
    }
    if (!flag) printf("-1\n");
    return 0;
}


//指定小写字母元音/辅音
//给出第i个位置是元音/辅音蕴涵j位置元音/辅音
//给定字符串st,求字典序不小于它的最小的合法2-sat方案
#include <bits/stdc++.h>
#define MAXN 500
#define MAXM 512345

using namespace std;
typedef int arrayN[MAXN], arrayM[MAXM];

char g[30], st[MAXN];
arrayN fir0, low, dfn, inVec, cnt, belong;
arrayN deg, con0, con1, fir1, topOrder, col;
arrayM e0, nxt0, e1, nxt1;
int num, now, tot, nextAlp[30][2], firAlp[2];
vector<int> vec;

int getKind(char ch) {
    if (ch == 'V') return 0;
    else return 1;
}

void link0(int u, int v) {
    e0[++num] = v, nxt0[num] = fir0[u];
    fir0[u] = num;
}

void link1(int u, int v) {
    e1[++num] = v, nxt1[num] = fir1[u];
    fir1[u] = num;
}

void tarjan(int x) {
    low[x] = dfn[x] = ++now;
    vec.push_back(x);
    for (int p = fir0[x], q; p; p = nxt0[p])
        if (!inVec[q = e0[p]])
            if (!dfn[e0[p]]) {
                tarjan(e0[p]);
                low[x] = min(low[x], low[e0[p]]);
            } else low[x] = min(low[x], dfn[e0[p]]);
    if (low[x] == dfn[x]) {
        cnt[belong[x] = ++tot] = 1;
        inVec[x] = 1;
        for (; vec.back() != x; vec.pop_back()) {
            int q = vec.back();
            inVec[q] = 1;
            cnt[belong[q] = tot]++;
        }
        vec.pop_back();
    }
}

void topSort() {
    int l = 1, r = 0;
    for (int i = 1; i <= tot; ++i)
        if (deg[i] == 0) topOrder[++r] = i;
    for (; l <= r; ++l) {
        int u = topOrder[l];
        for (int p = fir1[u]; p; p = nxt1[p]) {
            --deg[e1[p]];
            if (deg[e1[p]] == 0) topOrder[++r] = e1[p];
        }
    }
}
int getDAG(int n) {
    for (int i = 1; i <= n * 2; ++i)
        dfn[i] = low[i] = belong[i] = inVec[i] = deg[i] = 0;
    now = tot = num = 0;
    for (int i = 1; i <= n * 2; ++i)
        if (!dfn[i]) tarjan(i);
    for (int i = 1; i <= n; ++i)
        if (belong[i] == belong[con0[i]]) return 0;
    for (int i = 1; i <= 2 * n; ++i) {
        for (int p = fir0[i]; p; p = nxt0[p]) {
            int q = e0[p];
            if (belong[i] == belong[q]) continue;
            link1(belong[q], belong[i]);
            deg[belong[i]]++;
        }
        con1[belong[i]] = belong[con0[i]];
        con1[belong[con0[i]]] = belong[i];
    }
    topSort();
    return 1;
}

int dye(int x, int co) {
    if (col[x]) {
        return (co == col[x]);
    }
    col[x] = co;
    for (int p = fir1[x]; p; p = nxt1[p])
        if (!dye(e1[p], co)) return 0;
    return 1;
}

int originDye(int p) {
    for (int i = 1; i <= p + 1; ++i) {
        int pos = belong[i];
        if (getKind(g[st[i - 1] - 'a'])) pos = con1[pos];
        if (col[pos] == 2) return 0;
        col[pos] = 1;
        if (!dye(con1[pos], 2)) return 0;
    }
    return 1;
}
int DAGDye(int n) {
    for (int i = 1; i <= n; ++i) {
        int x = topOrder[i];
        if (!col[x]) {
            col[x] = 1;
            if (!dye(con1[x], 2)) return 0;
        }
    }
    return 1;
}

int finalCheck(int n, int p) {
    for (int i = 1; i <= n; ++i) {
        if (col[belong[i]] != 1 && col[belong[con0[i]]] != 1) return 0;
    }
    return 1;
}

int solve(int n, int p) {
    memset(col, 0, sizeof(col));
    if (!originDye(p)) return 0;
    if (!DAGDye(tot)) return 0;
    return finalCheck(n, p);
}

void getNextAlp() {
    int len = strlen(g);
    firAlp[1] = firAlp[0] = 'z' + 1;
    for (int i = 0; i < len; ++i) {
        nextAlp[i][0] = nextAlp[i][1] = 'z' + 1;
        int k = getKind(g[i]);
        firAlp[k] = min(firAlp[k], i + 'a');
        for (int j = i + 1; j < len; ++j) {
            int k = getKind(g[j]);
            nextAlp[i][k] = min(nextAlp[i][k], 'a' + j);
        }
        if (nextAlp[i][0] > nextAlp[i][1])
            swap(nextAlp[i][0], nextAlp[i][1]);
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    scanf("%s", g);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        con0[i] = i + n;
        con0[i + n] = i;
    }
    num = 0;
    for (int i = 1; i <= m; ++i) {
        char t1, t2;
        int pos1, pos2;
        scanf("%d %c %d %c\n", &pos1, &t1, &pos2, &t2);
        //  if (i == 50 && n == 50 && m == 50) printf("%d %c %d %c\n", pos1, t1, pos2, t2);
        int k1 = getKind(t1);
        int k2 = getKind(t2);
        pos1 += k1 * n;
        pos2 += k2 * n;
        link0(pos1, pos2);
        link0(con0[pos2], con0[pos1]);
    }
    scanf("%s", st);
    // if (n == 50 && m == 50) printf("%s\n", st);
    getNextAlp();
    if (getDAG(n) == 0) {
        printf("-1\n");
        return 0;
    }
    int flag = solve(n, n - 1);
    for (int i = n - 1; i >= 0 && !flag; --i) {
        int tmp = st[i] - 'a';
        for (int j = 0; j <= 1 && !flag; ++j)
            if (nextAlp[st[i] - 'a'][j] <= 'z') {
                st[i] = nextAlp[tmp][j];
                flag = solve(n, i);
                if (flag) {
                    for (int k = i + 1; k <= n - 1; ++k) {
                        int u = firAlp[0];
                        int v = firAlp[1];
                        if (u > v) swap(u, v);
                        st[k] = u;
                        if (solve(n, k)) continue;
                        st[k] = v;
                    }
                }
            }
    }
    if (!flag) printf("-1\n");
    else printf("%s\n", st);
    return 0;
}


//指定小写字母元音/辅音
//给出第i个位置是元音/辅音蕴涵j位置元音/辅音
//给定字符串st,求字典序不小于它的最小的合法2-sat方案
#include <bits/stdc++.h>
#define MAXN 500
#define MAXM 512345

using namespace std;
typedef int arrayN[MAXN], arrayM[MAXM];

char g[30], st[MAXN];
arrayN fir0, low, dfn, inVec, cnt, belong;
arrayN deg, con0, con1, fir1, topOrder, col;
arrayM e0, nxt0, e1, nxt1;
int num, now, tot, nextAlp[30][2], firAlp[2];
vector<int> vec;

int getKind(char ch) {
    if (ch == 'V') return 0;
    else return 1;
}

void link0(int u, int v) {
    e0[++num] = v, nxt0[num] = fir0[u];
    fir0[u] = num;
}

void link1(int u, int v) {
    e1[++num] = v, nxt1[num] = fir1[u];
    fir1[u] = num;
}

void tarjan(int x) {
    low[x] = dfn[x] = ++now;
    vec.push_back(x);
    for (int p = fir0[x], q; p; p = nxt0[p])
        if (!inVec[q = e0[p]])
            if (!dfn[e0[p]]) {
                tarjan(e0[p]);
                low[x] = min(low[x], low[e0[p]]);
            } else low[x] = min(low[x], dfn[e0[p]]);
    if (low[x] == dfn[x]) {
        cnt[belong[x] = ++tot] = 1;
        inVec[x] = 1;
        for (; vec.back() != x; vec.pop_back()) {
            int q = vec.back();
            inVec[q] = 1;
            cnt[belong[q] = tot]++;
        }
        vec.pop_back();
    }
}

void topSort() {
    int l = 1, r = 0;
    for (int i = 1; i <= tot; ++i)
        if (deg[i] == 0) topOrder[++r] = i;
    for (; l <= r; ++l) {
        int u = topOrder[l];
        for (int p = fir1[u]; p; p = nxt1[p]) {
            --deg[e1[p]];
            if (deg[e1[p]] == 0) topOrder[++r] = e1[p];
        }
    }
}
int getDAG(int n) {
    for (int i = 1; i <= n * 2; ++i)
        dfn[i] = low[i] = belong[i] = inVec[i] = deg[i] = 0;
    now = tot = num = 0;
    for (int i = 1; i <= n * 2; ++i)
        if (!dfn[i]) tarjan(i);
    for (int i = 1; i <= n; ++i)
        if (belong[i] == belong[con0[i]]) return 0;
    for (int i = 1; i <= 2 * n; ++i) {
        for (int p = fir0[i]; p; p = nxt0[p]) {
            int q = e0[p];
            if (belong[i] == belong[q]) continue;
            link1(belong[q], belong[i]);
            deg[belong[i]]++;
        }
        con1[belong[i]] = belong[con0[i]];
        con1[belong[con0[i]]] = belong[i];
    }
    topSort();
    return 1;
}

int dye(int x, int co) {
    if (col[x]) {
        return (co == col[x]);
    }
    col[x] = co;
    for (int p = fir1[x]; p; p = nxt1[p])
        if (!dye(e1[p], co)) return 0;
    return 1;
}

int originDye(int p, int n) {
    int all = -1;
    if (firAlp[0] > 'z') all = 0;
    if (firAlp[1] > 'z') all = 1;
    if (all >= 0)
        for (int i = 1; i <= n; ++i) {
            int pos1 = i + all * n;
            int pos0 = con1[pos1];
            if (col[pos0] == 2) return 0;
            col[pos0] = 1;
            if (!dye(pos1, 2)) return 0;
        }
    for (int i = 1; i <= p + 1; ++i) {
        int pos = belong[i];
        if (getKind(g[st[i - 1] - 'a'])) pos = con1[pos];
        if (col[pos] == 2) return 0;
        col[pos] = 1;
        if (!dye(con1[pos], 2)) return 0;
    }
    return 1;
}
int DAGDye(int n) {
    for (int i = 1; i <= n; ++i) {
        int x = topOrder[i];
        if (!col[x]) {
            col[x] = 1;
            if (!dye(con1[x], 2)) return 0;
        }
    }
    return 1;
}

int finalCheck(int n, int p) {
    for (int i = 1; i <= n; ++i) {
        if (col[belong[i]] != 1 && col[belong[con0[i]]] != 1) return 0;
    }
    return 1;
}

int solve(int n, int p) {
    memset(col, 0, sizeof(col));
    if (!originDye(p, n)) return 0;
    if (!DAGDye(tot)) return 0;
    return finalCheck(n, p);
}

void getNextAlp() {
    int len = strlen(g);
    firAlp[1] = firAlp[0] = 'z' + 1;
    for (int i = 0; i < len; ++i) {
        nextAlp[i][0] = nextAlp[i][1] = 'z' + 1;
        int k = getKind(g[i]);
        firAlp[k] = min(firAlp[k], i + 'a');
        for (int j = i + 1; j < len; ++j) {
            int k = getKind(g[j]);
            nextAlp[i][k] = min(nextAlp[i][k], 'a' + j);
        }
        if (nextAlp[i][0] > nextAlp[i][1])
            swap(nextAlp[i][0], nextAlp[i][1]);
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    scanf("%s", g);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        con0[i] = i + n;
        con0[i + n] = i;
    }
    num = 0;
    for (int i = 1; i <= m; ++i) {
        char t1, t2;
        int pos1, pos2;
        scanf("%d %c %d %c\n", &pos1, &t1, &pos2, &t2);
        //  if (i == 50 && n == 50 && m == 50) printf("%d %c %d %c\n", pos1, t1, pos2, t2);
        int k1 = getKind(t1);
        int k2 = getKind(t2);
        pos1 += k1 * n;
        pos2 += k2 * n;
        link0(pos1, pos2);
        link0(con0[pos2], con0[pos1]);
    }
    scanf("%s", st);
    // if (n == 50 && m == 50) printf("%s\n", st);
    getNextAlp();
    if (getDAG(n) == 0) {
        printf("-1\n");
        return 0;
    }
    int flag = solve(n, n - 1);
    for (int i = n - 1; i >= 0 && !flag; --i) {
        int tmp = st[i] - 'a';
        for (int j = 0; j <= 1 && !flag; ++j)
            if (nextAlp[st[i] - 'a'][j] <= 'z') {
                st[i] = nextAlp[tmp][j];
                flag = solve(n, i);
                if (flag) {
                    for (int k = i + 1; k <= n - 1; ++k) {
                        int u = firAlp[0];
                        int v = firAlp[1];
                        if (u > v) swap(u, v);
                        st[k] = u;
                        if (solve(n, k)) continue;
                        st[k] = v;
                    }
                }
            }
    }
    if (!flag) printf("-1\n");
    else printf("%s\n", st);
    return 0;
}


#include<bits/stdc++.h>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define FZ(n) memset((n),0,sizeof(n))
#define FMO(n) memset((n),-1,sizeof(n))
#define MC(n,m) memcpy((n),(m),sizeof(n))
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define FOR(x,y) for(__typeof(y.begin())x=y.begin();x!=y.end();x++)
#define IOS ios_base::sync_with_stdio(0); cin.tie(0)
// Let's Fight!

const int MAXN = 205;

int N, M, L;
string s, sp;
bool sarr[MAXN];

vector<int> oedge[MAXN*2], edge[MAXN*2], rdge[MAXN*2];
int cnt;
int vis[MAXN*2], scc[MAXN*2];
int ord[MAXN*2];

void dfs(int x)
{
  if(vis[x] != -1) return;
  vis[x] = -2;
  for(auto c: edge[x])
    dfs(c);
  ord[cnt] = x;
  vis[x] = cnt++;
}

void dfs2(int x, int sc)
{
  if(scc[x] != -1) return;
  scc[x] = sc;
  for(auto c: rdge[x])
    dfs2(c, sc);
}

bool feasible(string pre)
{
  for(int i=0; i<2*N; i++)
    edge[i] = oedge[i];
  for(int i=0; i<(int)pre.size(); i++)
  {
    if(sarr[pre[i]-'a'])
      edge[i].PB(i+N);
    else
      edge[i+N].PB(i);
  }

  for(int i=0; i<2*N; i++)
    rdge[i].clear();
  for(int i=0; i<2*N; i++)
    for(auto c: edge[i])
      rdge[c].PB(i);

  for(int i=0; i<2*N; i++)
    vis[i] = scc[i] = -1;
  cnt = 0;
  for(int i=0; i<2*N; i++)
    if(vis[i] == -1)
      dfs(i);
  for(int i=2*N-1; i>=0; i--)
  {
    int v = ord[i];
    if(scc[v] == -1)
      dfs2(v, v);
  }

  for(int i=0; i<N; i++)
    if(scc[i] == scc[i+N])
      return false;

  return true;
}

int main()
{
  IOS;

  cin>>sp;
  cin>>N>>M;

  L = sp.size();
  for(int i=0; i<L; i++)
    sarr[i] = (sp[i] == 'C');

  bool anyv = false, anyc = false;
  for(int i=0; i<L; i++)
  {
    if(sarr[i])
      anyc = true;
    else
      anyv = true;
  }

  for(int i=0; i<M; i++)
  {
    int p1, p2;
    char c1, c2;
    cin>>p1>>c1>>p2>>c2;
    int v1 = p1 - 1 + (c1 == 'C') * N;
    int v2 = p2 - 1 + (c2 == 'C') * N;
    int u1 = p1 - 1 + (c1 != 'C') * N;
    int u2 = p2 - 1 + (c2 != 'C') * N;
    oedge[v1].PB(v2);
    oedge[u2].PB(u1);
  }

  for(int i=0; i<N; i++)
  {
    if(!anyv)
      oedge[i].PB(i+N);
    if(!anyc)
      oedge[i+N].PB(i);
  }
  cin>>s;

  string cur = s;
  bool ok = false;
  while(1)
  {
    if(feasible(cur))
    {
      ok = true;
      break;
    }
    while(!cur.empty() && cur.back() - 'a' == L - 1)
      cur.pop_back();
    if(cur.empty())
      break;
    cur.back()++;
  }

  if(!ok)
  {
    cout<<-1<<endl;
    return 0;
  }

  while((int)cur.size() < N)
  {
    for(int i=0; i<L; i++)
    {
      cur.PB('a'+i);
      if(feasible(cur))
        break;
      else
        cur.pop_back();
    }
  }

  cout<<cur<<endl;

  return 0;
}

// ntuj - njjluppzrq1f4gme9brs6


#include <bits/stdc++.h>
#define PB push_back
#define MP make_pair
#define F first
#define S second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;

#define ALL(x) (x).begin(),(x).end()

const int MAXN=210;

inline int TYPE(char c) {
    return c=='V'?0:1;
}

char word[30];
VI v[2],e[MAXN*2];
int n,m;
char s[MAXN];

int choose[MAXN*2];

VI to[MAXN*2];
bool vis[MAXN*2];
int from;

void DFS1(int x) {
    to[from].PB(x);
    vis[x]=1;
    if(x==(1^from))
        choose[from]=-1;
    for(int u:e[x])
        if(!vis[u])
            DFS1(u);
}

char ans[MAXN];

bool run(int x,bool bigger) {
    if(x>n) {
        if(bigger)
            return 1;
        else
            return 0;
    }
    if(bigger) {
        if(choose[2*x]>0 || choose[2*x+1]==-1) {
            if(SZ(v[0])) {
                ans[x]=v[0][0]+'a';
                if(choose[2*x]==0)
                    for(int u:to[2*x]) {
                        assert(choose[u]!=-1);
                        choose[u]++;
                    }
                if(run(x+1,bigger))
                    return 1;
                else {
                    if(choose[2*x]==0)
                        for(int u:to[2*x])
                            choose[u]--;
                    return 0;
                }
            }
            else
                return 0;
        }
        if(choose[2*x+1]>0 || choose[2*x]==-1) {
            if(SZ(v[1])) {
                ans[x]=v[1][0]+'a';
                if(choose[2*x+1]==0)
                    for(int u:to[2*x+1]) {
                        assert(choose[u]!=-1);
                        choose[u]++;
                    }
                if(run(x+1,bigger))
                    return 1;
                else {
                    if(choose[2*x+1]==0)
                        for(int u:to[2*x+1])
                            choose[u]--;
                    return 0;
                }
            }
            else
                return 0;
        }
        int type=TYPE(word[0]);
        ans[x]='a';
        for(int u:to[2*x+type]) {
            assert(choose[u]!=-1);
            choose[u]++;
        }
        if(run(x+1,bigger))
            return 1;
        else
            for(int u:to[2*x+type])
                choose[u]--;
        type^=1;
        if(SZ(v[type])) {
            ans[x]=v[type][0]+'a';
            for(int u:to[2*x+type]) {
                assert(choose[u]!=-1);
                choose[u]++;
            }
            if(run(x+1,bigger))
                return 1;
            else
                for(int u:to[2*x+type])
                    choose[u]--;
        }
        return 0;
    }
    else {
        if(choose[2*x]>0 || choose[2*x+1]==-1) {
            auto p=lower_bound(ALL(v[0]),s[x]-'a');
            if(p!=v[0].end()) {
                if(*p==s[x]-'a') {
                    ans[x]=s[x];
                    if(choose[2*x]==0)
                        for(int u:to[2*x]) {
                            assert(choose[u]!=-1);
                            choose[u]++;
                        }
                    if(run(x+1,0))
                        return 1;
                    if(choose[2*x]==0)
                        for(int u:to[2*x])
                            choose[u]--;
                    p++;
                    if(p==v[0].end())
                        return 0;
                }
                ans[x]=*p+'a';
                if(choose[2*x]==0)
                    for(int u:to[2*x]) {
                        assert(choose[u]!=-1);
                        choose[u]++;
                    }
                if(run(x+1,1))
                    return 1;
                if(choose[2*x]==0)
                    for(int u:to[2*x])
                        choose[u]--;
            }
            return 0;
        }
        if(choose[2*x+1]>0 || choose[2*x]==-1) {
        //  printf("x=%d\n",x);
            auto p=lower_bound(ALL(v[1]),s[x]-'a');
     //     printf("~~%d\n",*p);
            if(p!=v[1].end()) {
                if(*p==s[x]-'a') {
                    ans[x]=s[x];
                    if(choose[2*x+1]==0)
                        for(int u:to[2*x+1]) {
                            assert(choose[u]!=-1);
                            choose[u]++;
                        }
                    if(run(x+1,0))
                        return 1;
                    if(choose[2*x+1]==0)
                        for(int u:to[2*x+1])
                            choose[u]--;
                    p++;
                    if(p==v[1].end())
                        return 0;
                }
             // printf("~~%d\n",*p);
                ans[x]=*p+'a';
                if(choose[2*x+1]==0)
                    for(int u:to[2*x+1]) {
                        assert(choose[u]!=-1);
                        choose[u]++;
                    }
                if(run(x+1,1))
                    return 1;
                if(choose[2*x+1]==0)
                    for(int u:to[2*x+1])
                        choose[u]--;
            }
            return 0;
        }
        int type=TYPE(word[s[x]-'a']);
      //printf("x=%d,type=%d\n",x,type);
        ans[x]=s[x];
        for(int u:to[2*x+type]) {
       //   printf("u=%d\n",u);
            assert(choose[u]!=-1);
            choose[u]++;
        }
        if(run(x+1,0))
            return 1;
        for(int u:to[2*x+type])
            choose[u]--;
        if(word[s[x]-'a'+1]) {
            type=TYPE(word[s[x]-'a'+1]);
            ans[x]=s[x]+1;
            for(int u:to[2*x+type]) {
                assert(choose[u]!=-1);
                choose[u]++;
            }
            if(run(x+1,1))
                return 1;
            for(int u:to[2*x+type])
                choose[u]--;
            type^=1;
            auto p=upper_bound(ALL(v[type]),s[x]-'a');
            if(p!=v[type].end()) {
                ans[x]=*p+'a';
                for(int u:to[2*x+type]) {
                    assert(choose[u]!=-1);
                    choose[u]++;
                }
                if(run(x+1,1))
                    return 1;
                for(int u:to[2*x+type])
                    choose[u]--;
            }
        }
        return 0;
    }
}

int main() {
    int pos1,pos2,a,b;
    char t1[5],t2[5];
    scanf("%s",word);
    for(int i=0;word[i];i++)
        if(word[i]=='V')
            v[0].PB(i);
        else
            v[1].PB(i);
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++) {
        scanf("%d%s%d%s",&pos1,t1,&pos2,t2);
        if(t1[0]=='V')
            a=2*pos1;
        else
            a=2*pos1+1;
        if(t2[0]=='V')
            b=2*pos2;
        else
            b=2*pos2+1;
        e[a].PB(b);
        e[1^b].PB(1^a);
    }
    for(int i=2;i<=2*n+1;i++) {
        from=i;
        memset(vis,0,sizeof(vis));
        DFS1(i);
    }
   /* for(int i=2;i<=2*n+1;i++) {
        printf("%d:",i);
        for(int u:to[i])
            printf(" %d",u);
        puts("");
    }*/
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
        if(choose[2*i]==-1 && choose[2*i+1]==-1) {
            puts("-1");
            return 0;
        }
    bool re=run(1,0);
//  printf("(%d)\n",re);
    if(re)
        puts(ans+1);
    else
        puts("-1");
    return 0;
}

// ntuj - 7c80dwjaizotqxmich8x0


#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>          //cout<<fixed<<setprecision(10);
//#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
//#include <ctime>
//#include <memory.h>
//#include <cassert>

#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) ((int)strlen(X))
#define F first
#define S second
#ifdef ONLINE_JUDGE
#define FILEIO(name) \
    freopen(name".in", "r", stdin); \
    freopen(name".out", "w", stdout);
#else
#define FILEIO(name)
#endif

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> ii;
/*#include<complex.h>
typedef complex<double> co;
#define X real()
#define Y imag()*/

const int maxn = 200 + 10;

//O(V+E),E<=4n(n-1)
struct TwoSAT {
  int n;
  vector<int> G[maxn*2];
  bool mark[maxn*2];
  bool var_ans[maxn];
  int S[maxn*2], c;

  bool dfs(int x) {
    if (mark[x^1]) return false;
    if (mark[x]) return true;
    mark[x] = true;
    S[c++] = x;
    for (int i = 0; i < G[x].size(); i++)
      if (!dfs(G[x][i])) return false;
    return true;
  }

  void init(int n) {
    this->n = n;
    for (int i = 0; i < n*2; i++) G[i].clear();
  }

  // x = xval or y = yval
  int la1,la2;
  void add_clause(int x, int xval, int y, int yval) {
    x = x * 2 + xval;
    y = y * 2 + yval;
    G[x^1].push_back(y);
    G[y^1].push_back(x);
    la1=x;
    la2=y;
  }

  void del_lastclause(){
    G[la1^1].pop_back();
    G[la2^1].pop_back();
  }

  bool solve() {
    memset(mark, 0, sizeof(mark));
    for(int i = 0; i < n*2; i += 2)
      if(!mark[i] && !mark[i+1]) {
        c = 0;
        if(!dfs(i)) {
          while(c > 0) mark[S[--c]] = false;
          if(!dfs(i+1)) return false;
        }
      }
    for(int i = 0; i < n; i++)
      var_ans[i]=mark[i*2+1];
    return true;
  }
}ts;

char ans[210];
bool vc[30];
char s[210];

int main()
{
    char vctmp[30];
    RS(vctmp);
    int maxalpha=LEN(vctmp);
    REP(i,0,maxalpha)vc[i]=(vctmp[i]=='C');
    DRII(n,m);
    ts.init(n);
    int A,B;
    char tmp1[4],tmp2[4];
    REP(i,0,m){
        scanf("%d%s%d%s",&A,tmp1,&B,tmp2);
        A--;B--;
        ts.add_clause(A,tmp1[0]!='C',B,tmp2[0]=='C');
        //cout<<A<<' '<<(tmp1[0]!='C')<<' '<<B<<' '<<(tmp2[0]=='C')<<endl;
    }
    TwoSAT in=ts;
    RS(s);

    REP(i,0,n){
        ts.add_clause(i,vc[s[i]-'a'],i,vc[s[i]-'a']);
    }
    if(ts.solve()){
        puts(s);
        return 0;
    }

    for(int L=n-1;L>=0;L--){
        ts=in;
        REP(i,0,L){
            ts.add_clause(i,vc[s[i]-'a'],i,vc[s[i]-'a']);
            //cout<<x<<' '<<vc[s[x]-'a']<<endl;
            ans[i]=s[i];
        }
        if(!ts.solve())continue;
        else{
            //cout<<"STEP1: "<<L<<endl;
            int noans=1;
            bool done[210][2];
            MS0(done);
            int x=L;
            REP(i,s[x]-'a'+1,maxalpha){
                if(done[x][vc[i]])continue;
                ts.add_clause(x,vc[i],x,vc[i]);
                done[x][vc[i]]=1;
                //cout<<x<<' '<<vc[i]<<endl;
                if(ts.solve()){
                    //cout<<'a'+i<<endl;
                    ans[x]=i+'a';
                    x++;
                    noans=0;
                    break;
                }
                else ts.del_lastclause();
            }
            if(noans)continue;
            else{
                for(;x<n;x++){
                    noans=1;
                    REP(i,0,maxalpha){
                        if(done[x][vc[i]])continue;
                        ts.add_clause(x,vc[i],x,vc[i]);
                        done[x][vc[i]]=1;
                        if(ts.solve()){
                            noans=0;
                            ans[x]=i+'a';
                            break;
                        }
                        else ts.del_lastclause();
                    }
                    if(noans)break;
                }
                if(noans)continue;
                else puts(ans);
                return 0;
            }
        }
    }
    puts("-1");
    return 0;
}

// ntuj - 5cnjdz1uolokhg2endffc


#include<bits/stdc++.h>
using namespace std;
#define FZ(n) memset((n),0,sizeof(n))
#define FMO(n) memset((n),-1,sizeof(n))
#define MC(n,m) memcpy((n),(m),sizeof(n))
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define FOR(x,y) for(__typeof(y.begin())x=y.begin();x!=y.end();x++)
#define ALL(x) x.begin(),x.end()
#define IOS ios_base::sync_with_stdio(0);cin.tie(0)
#ifdef ONLINE_JUDGE
#define FILEIO(name) \
  freopen(name".in", "r", stdin); \
  freopen(name".out", "w", stdout);
#else
#define FILEIO(name)
#endif

#define _TOKEN_CAT2(x, y) x ## y
#define _TOKEN_CAT(x, y) _TOKEN_CAT2(x, y)
#define _MACRO_OVERL3(_1, _2, _3, _N, ...) _N
#define _RANGE1(a) int _TOKEN_CAT(_t, __LINE__)=0; _TOKEN_CAT(_t, __LINE__)<(a); (_TOKEN_CAT(_t, __LINE__))++
#define _RANGE2(i, a) int (i)=0; (i)<(a); (i)++
#define _RANGE3(i, a, b) int (i)=a; (i)<(b); (i)++
#define range(...) _MACRO_OVERL3(__VA_ARGS__, _RANGE3, _RANGE2, _RANGE1)(__VA_ARGS__)

const int MX = 1000;

typedef pair<int, int> pii;
string T, S;
int N, M, C;
vector<pair<pii, pii>> rules;
vector<int> el[MX];

int dfn[MX], low[MX], scc[MX], did, scn;
bool ins[MX];
stack<int> st;

void dfs(int v) {
    dfn[v] = low[v] = ++did;
    ins[v] = true;
    st.push(v);

    for (auto u: el[v]) {
        if (not dfn[u]) {
            dfs(u);
            low[v] = min(low[u], low[v]);
        } else if (ins[u]) low[v] = min(low[v], dfn[u]);
    }

    if (dfn[v] == low[v]) {
        scn ++;
        int u;
        do {
            u = st.top(); st.pop();
            //cout << u << ' ' << v << endl;
            ins[u] = false;
            scc[u] = scn;
        } while (u != v);
    }
    //cout << v << ' ' << dfn[v] << ' ' << low[v] << endl;
}

bool test() {
    //cout << S << endl;
    for (int i=0; i<N*2; i++) {
        el[i].clear();
    }
    for (int i=0; i<N; i++) {
        if (S[i] == '?') break;
        char c = S[i];
        int t = (T[c-'a'] == 'C');
        int p = i*2+t;
        el[p^1].PB(p);
    }

    for (auto pp: rules) {
        pii p1 = pp.F, p2 = pp.S;
        int i1 = p1.F*2+p1.S, i2 = p2.F*2+p2.S;
        el[i1].PB(i2);
        el[i2^1].PB(i1^1);
    }

    //for (int i=0; i<N*2; i++) {
        //cout << i << " : " ;
        //for (auto v: el[i]) {
            //cout << v << ' ';
        //} cout << endl;
    //}

    fill(dfn, dfn+(N*2), 0);

    did = scn = 0;
    for (int i=0; i<N*2; i++) {
        if (not dfn[i]) dfs(i);
    }

    for (int i=0; i<N; i++) {
        if (scc[i*2] == scc[i*2+1]) return false;
    }
    return true;
}

int main() {

    IOS;
    while(cin >> T) {
        rules.clear();

        C = T.length();
        cin >> N >> M;
        for (int i=0; i<M; i++) {
            int p1, p2; string t1, t2; cin >> p1 >> t1 >> p2 >> t2;
            rules.PB({{p1-1, int(t1=="C")}, {p2-1, int(t2=="C")}});
        }
        cin >> S;

        int npos = N-1;
        bool flag = test();
        if (not flag) {
            while (npos >= 0) {
                S[npos]++;
                int mem = 0;
                while (S[npos] < 'a'+C) {
                    int t = T[S[npos]-'a'] == 'C';
                    if (mem & (1<<t)){
                        S[npos] ++;
                        continue;
                    }
                    mem |= (1<<t);
                    if (test()) {
                        flag = true;
                        break;
                    }
                    S[npos] ++;
                }

                if (flag) break;
                else S[npos--] = '?';
            }
        }

        if (not flag) {
            cout << -1 << endl;
        } else {
            npos ++;
            flag = true;
            while (npos < N) {
                bool can = false;
                int mem = 0;
                for (char c='a'; c<('a'+C); c++) {
                    int t = (T[c-'a'] == 'C');
                    if (mem & (1<<t)){
                        continue;
                    }
                    mem |= (1<<t);
                    S[npos] = c;
                    if (test()) {
                        can = true;
                        break;
                    }
                }
                if (not can) {
                    flag = false; break;
                }
                npos ++;
            }
            if (flag)
                cout << S << endl;
            else
                cout << -1 << endl;
        }

    }

    return 0;
}

// ntuj - 4agxurl2y4sythkg5h6jw


#include<stdio.h>
char s[27],t[201],ans[201];
bool history[401];
bool usedC[401], usedV[401];
bool map[401][401];
inline int C(int x){
	return x+x;
}
inline int V(int x){
	return x+x+1;
}
void dfs(bool *used, int nn,int p){
	used[p]=true;
	for(int i=0;i<nn;i++){
		if(map[p][i]&&!used[i]){
			dfs(used,nn,i);
		}
	}
}
bool check(bool *used, int n){
	for(int i=0;i<n;i++)
		if(used[i+i]&&used[i+i+1])
			return false;
	return true;
}
int main(){
	int i,j,k;
	int n,m,sn;
	while(scanf("%s%d%d",s,&n,&m)==3){
		for(sn=0;s[sn];sn++);
		int nn=n+n;
		for(i=0;i<nn;i++){
			for(j=0;j<nn;j++){
				map[i][j]=false;
			}
			history[i]=false;
		}
		while(m--){
			int p1,p2;
			char t1[10],t2[10];
			scanf("%d%s%d%s",&p1,&t1,&p2,&t2);
			p1--; p2--;
			p1=*t1=='C'?C(p1):V(p1);
			p2=*t2=='C'?C(p2):V(p2);
			map[p1][p2]=true;
			map[p2^1][p1^1]=true;
		}
		scanf("%s",t);
		bool greater=false;
		for(i=0;i<n;i++){
			bool checkedC=false, checkedV=false;
			bool okC=false, okV=false;
			int start=greater?0:t[i]-'a';
			for(j=start;j<sn;j++){
				bool *used;
				if(s[j]=='C'){
					if(!checkedC){
						checkedC=true;
						for(k=0;k<nn;k++){
							usedC[k]=history[k];
						}
						dfs(usedC,nn,C(i));
						okC=check(usedC,n);
					}
					if(!okC) continue;
					used=usedC;
				}
				if(s[j]=='V'){
					if(!checkedV){
						checkedV=true;
						for(k=0;k<nn;k++){
							usedV[k]=history[k];
						}
						dfs(usedV,nn,V(i));
						okV=check(usedV,n);
					}
					if(!okV) continue;
					used=usedV;
				}
				if(!greater&&j==start){
					int p=sn-1, rstart=0;
					for(k=i+1;k<n;k++){
						rstart=t[k]-'a';
						if(used[C(k)]){
							for(p=sn-1;p>=rstart;p--){
								if(s[p]=='C') break;
							}
						} else if(used[V(k)]){
							for(p=sn-1;p>=rstart;p--){
								if(s[p]=='V') break;
							}
						} else {
							p=sn-1;
						}
						if(p!=rstart) break;
					}
					if(p<rstart) continue;
				}
				ans[i]=j+'a';
				for(k=0;k<nn;k++){
					history[k]=used[k];
				}
				break;
			}
			if(!s[j]) break;
			if(j>start) greater=true;
		}
		if(i==n){
			ans[n]=0;
			puts(ans);
		} else {
			puts("-1");
		}
	}
}
// ntuj - 4bwsy8lceftzrvqos7jof


#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PII pair<int,int>
#define VPII vector<pair<int,int> >
#define PLL pair<long long,long long>
#define F first
#define S second
typedef long long LL;
using namespace std;
const int MOD = 1e9+7;
const int SIZE = 410;
// template end here
struct SCC{
    int n,used[SIZE],order[SIZE],gg[SIZE];
    vector<int>e[SIZE],ae[SIZE],ge[SIZE],emp;
    int id,gn;
    void init(int _n){
        n=_n;
        memset(used,0,sizeof(int)*n);
        REP(i,n){
            e[i]=ae[i]=ge[i]=emp;
        }
    }
    void add_edge(int x,int y){
        e[x].PB(y);
        ae[y].PB(x);
    }
    void pop(int x){
        e[x].pop_back();
        ae[x^1].pop_back();
    }
    void dfs1(int x){
        if(used[x]==1)return;
        used[x]=1;
        REP(i,SZ(e[x])){
            int y=e[x][i];
            dfs1(y);
        }
        order[--id]=x;
    }
    void dfs2(int x){
        if(used[x]==2)return;
        gg[x]=gn;
        used[x]=2;
        REP(i,SZ(ae[x])){
            int y=ae[x][i];
            if(used[y]==2){
                //if(gg[y]!=gg[x])ge[gg[y]].PB(gg[x]);
            }
            else dfs2(y);
        }
    }
    bool make_scc(){
        memset(used,0,sizeof(int)*n);
        gn=0;
        id=n;
        REP(i,n)
            dfs1(i);
        REP(i,n){
            if(used[order[i]]!=2){
                dfs2(order[i]);
                gn++;
            }
        }
        REP(i,n){
            if(gg[i]==gg[i+1])return 0;
            i++;
        }
        return 1;
        /*REP(i,gn){
            sort(ALL(ge[i]));
            ge[i].resize(unique(ALL(ge[i]))-ge[i].begin());
        }*/
    }
}scc;
char letters[30];
char input[210],s[210];
int ty(char c){
    if(c=='V')return 1;
    return 0;
}
bool check(int n){
    bool res;
    REP(i,n){
        if(s[i]){
            scc.add_edge(i*2+1-ty(letters[s[i]-'a']),i*2+ty(letters[s[i]-'a']));
        }
    }
    res=scc.make_scc();
    REP(i,n){
        if(s[i])scc.pop(i*2+1-ty(letters[s[i]-'a']));
    }
    return res;
}
int main(){
    RS(letters);
    int sz=LEN(letters);
    DRII(n,m);
    scc.init(2*n);
    REP(i,m){
        int x,y;
        char s1[14],s2[14];
        scanf("%d%s%d%s",&x,s1,&y,s2);
        x--;y--;
        scc.add_edge(x*2+ty(s1[0]),y*2+ty(s2[0]));
        scc.add_edge(y*2+1-ty(s2[0]),x*2+1-ty(s1[0]));
    }
    RS(input);
    strcpy(s,input);
    if(check(n))puts(input);
    else{
        bool err=1;
        REPP(i,1,sz){
            if(letters[i]!=letters[0])err=0;
        }
        if(err){
            puts("-1");
            return 0;
        }
        for(int i=n-1;i>=0;i--){
            set<char>c_used;
            for(int j=input[i]+1;j<'a'+sz;j++){
                if(!c_used.count(letters[j-'a'])){
                    strcpy(s,input);
                    c_used.insert(letters[j-'a']);
                    s[i]=j;
                    REPP(k,i+1,n)s[k]=0;
                    if(check(n)){
                        REPP(k,i+1,n){
                            set<char>c_used2;
                            REP(cc,sz){
                                if(!c_used2.count(letters[cc])){
                                    s[k]=cc+'a';
                                    if(SZ(c_used2))break;
                                    c_used2.insert(letters[cc]);
                                    if(check(n))break;
                                }
                            }
                        }
                        puts(s);
                        return 0;
                    }
                }
            }
        }
        puts("-1");
    }
    return 0;
}
// ntuj - k88b6oes9gbddxh31cwua


#include<bits/stdc++.h>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define FZ(n) memset((n),0,sizeof(n))
#define FMO(n) memset((n),-1,sizeof(n))
#define MC(n,m) memcpy((n),(m),sizeof(n))
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define FOR(x,y) for(__typeof(y.begin())x=y.begin();x!=y.end();x++)
#define IOS ios_base::sync_with_stdio(0); cin.tie(0)
// Let's Fight!

const int MAXN = 205;

int N, M, L;
string s, sp;
bool sarr[MAXN];

vector<int> oedge[MAXN*2], edge[MAXN*2], rdge[MAXN*2];
int cnt;
int vis[MAXN*2], scc[MAXN*2];
int ord[MAXN*2];
map<string, bool> mp;

string trans(string x)
{
  string ret;
  for(auto c: x)
    ret.PB(sarr[c-'a'] ? 'C' : 'V');
  return ret;
}

void dfs(int x)
{
  if(vis[x] != -1) return;
  vis[x] = -2;
  for(auto c: edge[x])
    dfs(c);
  ord[cnt] = x;
  vis[x] = cnt++;
}

void dfs2(int x, int sc)
{
  if(scc[x] != -1) return;
  scc[x] = sc;
  for(auto c: rdge[x])
    dfs2(c, sc);
}

bool feasible(string pre)
{
  for(int i=0; i<2*N; i++)
    edge[i] = oedge[i];
  for(int i=0; i<(int)pre.size(); i++)
  {
    if(sarr[pre[i]-'a'])
      edge[i].PB(i+N);
    else
      edge[i+N].PB(i);
  }

  for(int i=0; i<2*N; i++)
    rdge[i].clear();
  for(int i=0; i<2*N; i++)
    for(auto c: edge[i])
      rdge[c].PB(i);

  for(int i=0; i<2*N; i++)
    vis[i] = scc[i] = -1;
  cnt = 0;
  for(int i=0; i<2*N; i++)
    if(vis[i] == -1)
      dfs(i);
  for(int i=2*N-1; i>=0; i--)
  {
    int v = ord[i];
    if(scc[v] == -1)
      dfs2(v, v);
  }

  for(int i=0; i<N; i++)
    if(scc[i] == scc[i+N])
      return false;

  return true;
}

bool feas(string x)
{
  string t = trans(x);
  if(mp.count(t))
    return mp[t];
  return mp[t] = feasible(x);
}

int main()
{
  IOS;

  cin>>sp;
  cin>>N>>M;

  L = sp.size();
  for(int i=0; i<L; i++)
    sarr[i] = (sp[i] == 'C');

  bool anyv = false, anyc = false;
  for(int i=0; i<L; i++)
  {
    if(sarr[i])
      anyc = true;
    else
      anyv = true;
  }

  for(int i=0; i<M; i++)
  {
    int p1, p2;
    char c1, c2;
    cin>>p1>>c1>>p2>>c2;
    int v1 = p1 - 1 + (c1 == 'C') * N;
    int v2 = p2 - 1 + (c2 == 'C') * N;
    int u1 = p1 - 1 + (c1 != 'C') * N;
    int u2 = p2 - 1 + (c2 != 'C') * N;
    oedge[v1].PB(v2);
    oedge[u2].PB(u1);
  }

  for(int i=0; i<N; i++)
  {
    if(!anyv)
      oedge[i].PB(i+N);
    if(!anyc)
      oedge[i+N].PB(i);
  }
  cin>>s;

  string cur = s;
  bool ok = false;
  while(1)
  {
    if(feas(cur))
    {
      ok = true;
      break;
    }
    while(!cur.empty() && cur.back() - 'a' == L - 1)
      cur.pop_back();
    if(cur.empty())
      break;
    cur.back()++;
  }

  if(!ok)
  {
    cout<<-1<<endl;
    return 0;
  }

  while((int)cur.size() < N)
  {
    for(int i=0; i<L; i++)
    {
      cur.PB('a'+i);
      if(feas(cur))
        break;
      else
        cur.pop_back();
    }
  }

  cout<<cur<<endl;

  return 0;
}

// ntuj - jxz7xhmspi8ifvr9dk56q


#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < n; ++i)
#define ri(a) scanf("%d", &a)
#define rii(a, b) scanf("%d%d", &a, &b)
#define rs(s) scanf("%s", s)
#define PB push_back

vector<int> g[220 * 2];
bool ad[440][440]={{}};
int n, m, type[128], N;
char s[220], t[220]={};
bool color[220 * 2]={};
bool tmp[220][440];
char e;
bool solve(int x, bool fg = false) {
	if(x == n) return true;
	bool vt[2]={};
	memcpy(tmp[x], color, 440);
	for(char c = fg ? 'a' : s[x]; c <= e; ++c, fg = true) {
		if(color[x+x+type[c]^1]) continue;
		if(vt[type[c]]) continue;
		if(fg) vt[type[c]] = true;
		t[x] = c;
		int pos = x + x + type[c];
		for(int y: g[pos]) color[y] = true;
		if(solve(x + 1, fg)) return true;
		memcpy(color, tmp[x], 440);
	}
	return false;
}

int main() {
	char l[32];
	rs(l);
	e = strlen(l) + 'a' - 1;
	for(int i = 0; l[i]; ++i) {
		type['a' + i] = l[i] == 'V';
	}
	rii(n, m);
    rep(i, m) {
    	int x, y;
		char a[4], b[4];
		scanf("%d%s%d%s", &x, a, &y, b);
		x--; y--;
		int aa = x + x + (a[0] == 'V');
		int bb = y + y + (b[0] == 'V');
		ad[aa][bb] = true;
		ad[bb^1][aa^1] = true;
	}
	N = n * 2;
	rep(i, N) rep(j, N) rep(k, N) ad[i][j] |= ad[i][k] & ad[k][j];
	rep(i, N) rep(j, i) if(ad[j][i]) g[j].PB(i);
	rep(i, n) {
		int aa = i + i;
		int bb = i + i + 1;
		if(ad[aa][bb]&&ad[bb][aa]) {
			puts("-1");
			return 0;
		}
		else if(ad[aa][bb]) color[bb] = true;
		else if(ad[bb][aa]) color[aa] = true;
	}
	rs(s);
	if(solve(0)) puts(t);
	else puts("-1");
	return 0;
}

// ntuj - 9wk78in2w164tmqcghnuy


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
#define F first
#define S second
#define MP make_pair
#define PB push_back
int vc[27];   //v=1, c=0
int n,m;
int f[405][405];
char ans[205];
int vis[405];
int len;
int check(int node,int pos){
	int i;
	if((node&1)&&f[node][node-1]) return 0;
	if(!(node&1)&&f[node][node+1]) return 0;
	for(i=0;i<2*n;i++)
	  if(f[node][i]){
	  	if((i&1)&&f[i][i-1]) return 0;
	  	if(!(i&1)&&f[i][i+1]) return 0;
	  	if(i/2<pos){
	  		if(!(vc[(int)(ans[i/2]-'a')]^(i&1))) return 0;
	  	}
	  }
	return 1;
}
int dfs(int pos,int w){
	int i;
	if(pos==n) return 1;
	int vv=0,cc=0;
	for(i=w;i<len;i++){
		if(vc[i]==1&&vv) continue;
		if(vc[i]==0&&cc) continue;
		if(vc[i]==1){
			vv=1;
			if(check(2*pos,pos)){
				ans[pos]=(char)(i+'a');
				if(dfs(pos+1,0)){
					return 1;
				}
			}
		}
		else{
			cc=1;
			if(check(2*pos+1,pos)){
				ans[pos]=(char)(i+'a');
				if(dfs(pos+1,0)){
					return 1;
				}
			}
		}

	}
	return 0;
}
int main(void){
	int i,j,k;
	char mp[27];
	scanf("%s",mp);
	len=strlen(mp);
	for(i=0;mp[i];i++){
		if(mp[i]=='V') vc[i]=1;
		else vc[i]=0;
	}
	scanf("%d%d",&n,&m);
	for(i=0;i<m;i++){
		int a,b;
		char aa[2],bb[2];
		scanf("%d %s %d %s",&a,aa,&b,bb);
		a--,b--;
		if(aa[0]=='V'){
			if(bb[0]=='V') f[2*a][2*b]=1, f[2*b+1][2*a+1]=1;
			else f[2*a][2*b+1]=1, f[2*b][2*a+1]=1;
		}
		else{
			if(bb[0]=='V') f[2*a+1][2*b]=1, f[2*b+1][2*a]=1;
			else f[2*a+1][2*b+1]=1, f[2*b][2*a]=1;
		}
	}
	for(k=0;k<2*n;k++)
		for(i=0;i<2*n;i++)
			for(j=0;j<2*n;j++)
				if(f[i][k]&&f[k][j]) f[i][j]=1;
/*
	for(i=0;i<2*n;i++){
	  for(j=0;j<2*n;j++)
	    printf("%d ",f[i][j]);
	  printf("\n");
	}
*/
	char s[205];
	scanf("%s",s);
	strcpy(ans,s);
	int find=0;
	for(i=0;i<n;i++)
	  if(f[2*i][2*i+1]&&f[2*i+1][2*i]){
	  	printf("-1\n");
	  	return 0;
	  }
	for(i=strlen(s)-1;i>=-1;i--){
		int ok=1;
		for(j=0;j<=i;j++){
			int node=vc[(int)(s[j]-'a')]==1?2*j:2*j+1;
			if(!check(node,j+1)){
				ok=0;
				break;
			}
		}
	//	printf("%d %d\n",i,ok);
		if(ok){
			if(dfs(i+1,(int)(s[i+1]-'a')+1)){
				find=1;
				break;
			}
		}
	}
	if(find) printf("%s",ans);
	else printf("-1\n");
	return 0;
}

// ntuj - imcdlhv97zprmt6juwchm


#include <cstdio>
#include <cstring>
#include <vector>
#include <bitset>

const int MN = 205;

char VC[27];
int nx[27][2];
int N, M, Sig;
int bel[MN * 2], cnt;
std::vector<int> G[MN * 2], Dom[MN * 2];

int instk[MN * 2], stk[MN * 2], tp;
int dfn[MN * 2], low[MN * 2], dfc;
void Tarjan(int u) {
	low[u] = dfn[u] = ++dfc, stk[++tp] = u, instk[u] = 1;
	for (auto v : G[u])
		if (!dfn[v]) Tarjan(v), low[u] = std::min(low[u], low[v]);
		else if (instk[v]) low[u] = std::min(low[u], dfn[v]);
	if (low[u] == dfn[u]) {
		++cnt;
		for (int x = -1; x != u; --tp)
			bel[x = stk[tp]] = cnt,
			Dom[cnt].push_back(x),
			instk[x] = 0;
	}
}

std::bitset<400> Forbid[MN * 2], Tmp, Now[MN];

char A[MN], B[MN];
bool DFS(int i, int t) {
	if (i == N) return printf("%s\n", B), 1;
	int c = 0;
	if (!t) {
		int k = VC[A[i] - 'a'] == 'C';
		if (!Now[i][i << 1 | k]) {
			Now[i + 1] = Now[i] | Forbid[i << 1 | k];
			B[i] = A[i];
			if (DFS(i + 1, 0)) return 1;
		}
		c = A[i] - 'a' + 1;
	}
	int o = nx[c][0] > nx[c][1];
	if (nx[c][o] < Sig && !Now[i][i << 1 | o]) {
		Now[i + 1] = Now[i] | Forbid[i << 1 | o];
		B[i] = nx[c][o] + 'a';
		if (DFS(i + 1, 1)) return 1;
	} o ^= 1;
	if (nx[c][o] < Sig && !Now[i][i << 1 | o]) {
		Now[i + 1] = Now[i] | Forbid[i << 1 | o];
		B[i] = nx[c][o] + 'a';
		if (DFS(i + 1, 1)) return 1;
	}
	return 0;
}

int main() {
	scanf("%s", VC), Sig = strlen(VC);
	nx[Sig][0] = nx[Sig][1] = Sig;
	for (int i = Sig - 1; i >= 0; --i)
		nx[i][0] = VC[i] == 'V' ? i : nx[i + 1][0],
		nx[i][1] = VC[i] == 'C' ? i : nx[i + 1][1];
	scanf("%d%d", &N, &M);
	for (int i = 1; i <= M; ++i) {
		int u, v; char U[3], V[3];
		scanf("%d%s%d%s", &u, U, &v, V), --u, --v;
		(u <<= 1) |= *U == 'C', (v <<= 1) |= *V == 'C';
		G[u].push_back(v), G[v ^ 1].push_back(u ^ 1);
	}
	for (int i = 0; i < N + N; ++i) if (!dfn[i]) Tarjan(i);
	for (int i = 0; i < N; ++i)
		if (bel[i << 1] == bel[i << 1 | 1])
			return puts("-1"), 0;
	for (int i = 1; i <= cnt; ++i) {
		Tmp.reset();
		for (auto u : Dom[i]) Tmp[u ^ 1] = 1;
		for (auto u : Dom[i]) for (auto v : G[u]) Tmp |= Forbid[v];
		for (auto u : Dom[i]) Forbid[u] = Tmp;
	}
	scanf("%s", A);
	if (!DFS(0, 0)) puts("-1");
	return 0;
}

// Luogu : PinkRabbit


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>

const int N=205;

const int L=30;

char s[N];

int n,m,l,a[L],mn[L][2],vis[N<<1],rp[256];

std::vector<int> e[N<<1];

inline void add_edge(int u1,int p1,int u2,int p2){
	int x=u1<<1|p1,y=u2<<1|p2;
	e[x].push_back(y); e[y^1].push_back(x^1);
}

bool dfs(int u){
	if(vis[u^1]) return false; vis[u]=1;
	for(int i=0;i<(int)e[u].size();++i){
		int v=e[u][i]; if(!vis[v]&&!dfs(v)) return false;
	}
	return true;
}

inline bool ck(int j){
	for(int i=0;i<2*n;++i) vis[i]=0;
	for(int i=0;i<=j;++i) if(!dfs(i<<1|a[s[i]-'a'])) return false;
	for(int i=j+1;i<n;++i){
		if(mn[0][0]<l&&vis[i<<1]) s[i]=mn[0][0]+'a';
		else if(mn[0][1]<l&&vis[i<<1|1]) s[i]=mn[0][1]+'a';
		else{
			int x=mn[0][0],y=mn[0][1]; if(x>y) std::swap(x,y);
			if(x<l&&dfs(i<<1|a[x])) s[i]=x+'a';
			else if(y<l&&dfs(i<<1|a[y])) s[i]=y+'a';
			else return false;
		}
	}
	return true;
}

int main(){
	scanf("%s",s); l=strlen(s); rp['V']=0; rp['C']=1; mn[l][0]=mn[l][1]=l;
	for(int i=l-1,tmp[2]={l,l};i>=0;--i){
		tmp[a[i]=rp[(int)s[i]]]=i; mn[i][0]=tmp[0]; mn[i][1]=tmp[1];
	}
	scanf("%d%d",&n,&m); static char s1[5],s2[5];
	for(int i=1,p1,p2;i<=m;++i){
		scanf("%d%s%d%s",&p1,s1,&p2,s2);
		add_edge(--p1,rp[(int)s1[0]],--p2,rp[(int)s2[0]]);
	}
	scanf("%s",s); if(ck(n-1)) return printf("%s\n",s),0;
	for(int i=n-1;i>=0;--i){
		int c=s[i]-'a',x=mn[c+1][0],y=mn[c+1][1]; if(x>y) std::swap(x,y);
		if(x<l){ s[i]=x+'a'; if(ck(i)) return printf("%s\n",s),0; }
		if(y<l){ s[i]=y+'a'; if(ck(i)) return printf("%s\n",s),0; }
	}
	return puts("-1"),0;
}