#pragma comment(linker, "/STACK:60000000")

#include "testlib.h"    
#include <vector>
#include <set>
#include <utility>
#include <iostream>

using namespace std;

#define forn(i, n) for (int i = 0; i < int(n); ++i)

#define pb push_back

#define NMAX 100000
#define MMAX 99999
#define KMAX 100000
#define SUM 100000
#define SUMV 200000

vector<int> g[NMAX];
                            
int n, m, k;

bool check_nm(int n, int m) {
    return (n >= 2 && n <= NMAX && m >= 1 && m <= MMAX);    
}

bool check_k(int k) {
    return (k >= 1 && k <= KMAX);
}

set<pair<int, int> > edges;

int par[NMAX];

int l(int v) {
    if (v != par[v]) par[v] = l(par[v]);
    return par[v];
}

void un(int a, int b) {
    a = l(a);
    b = l(b);
    if (rand() & 1)
        par[a] = b;
    else
        par[b] = a; 
}

void check_init() {
    forn (i, n) par[i] = i;
}

bool check_edge(int a, int b) {
    if (a < 0 || a >= n || b < 0 || b >= n) return false;
    pair<int, int> p = make_pair(min(a, b), max(a, b));
    if (edges.count(p) != 0) return false;
    if (l(a) == l(b)) return false;
    edges.insert(p);
    un(a, b);
    return true;    
}

bool check_path(vector<int> &path) {
    if (path.size() < 2) return false;
    forn (i, path.size() - 1) {
        pair<int, int> p = make_pair(min(path[i], path[i + 1]), max(path[i], path[i + 1]));
        if (edges.count(p) == 0) return false;
    }
    if ((set<int> (path.begin(), path.end())).size() != path.size()) return false;
    return true;
}

bool check_suml(int suml) {
    return (suml <= SUM);
}

bool check_sumv(int sumv) {
    return (sumv <= SUMV);
}

vector<int> path[KMAX];

struct Answer
{
    string outcome;
    vector<int> level;
};

void readAnswer(Answer &answer, InStream * in) {
    answer.outcome = in -> readString();
    if (answer.outcome != "YES") return ;
    answer.level.resize(n);
    forn (i, n) answer.level[i] = in -> readInt();
}

bool check_answer(Answer &answer) {
    if (answer.outcome == "NO") return true;
    forn (i, k) {
        forn (j, path[i].size() - 1) {
            if (answer.level[path[i][j]] == answer.level[path[i][j + 1]]) return false;
        }
        forn (j, path[i].size() - 2) {
            bool cur = answer.level[path[i][j]] < answer.level[path[i][j + 1]];
            bool next = answer.level[path[i][j + 1]] < answer.level[path[i][j + 2]];

            if (cur != next) return false;
        }
    }   
    return true;
}

int main(int argc, char * argv[]) {
    registerTestlibCmd(argc, argv);

    n = inf.readInt();
    m = inf.readInt();

    if (!check_nm(n, m)) quitf(_fail, "incorrect N or M in test");

    check_init();
    
    forn (i, m) {
        int a = inf.readInt();
        int b = inf.readInt();

        --a; --b;
        if (!check_edge(a, b)) quitf(_fail, "incorrect edge %d %d in test", a + 1, b + 1);
        g[a].pb(b);
        g[b].pb(a);
    }

    k = inf.readInt();

    if (k < 1 || k > KMAX)
        quitf(_fail, "incorrect K value");

    int suml = 0;
    int sumv = 0;

    forn (i, k) {
        int v; 
        while ((v = inf.readInt()) != 0) path[i].pb(v - 1);
        suml += path[i].size() - 1;
        sumv += path[i].size();
        if (!check_path(path[i])) quitf(_fail, "incorrect path #%d in test", i + 1);
    }
    if (!check_suml(suml)) quitf(_fail, "incorrect test: paths too long, length = %d", suml);
    if (!check_sumv(sumv)) quitf(_fail, "incorrect test: paths too long, number of vertices = %d", sumv);

    Answer jury, user;
    readAnswer(jury, &ans);
    readAnswer(user, &ouf);

    forn (i, jury.level.size())
        if (jury.level[i] < 1 || jury.level[i] > n)
            quitf(_fail, "Номера зон должны быть от 1 до %d, однако номер зоны города %d у жюри равен %d", n, i + 1, jury.level[i]);

    forn (i, user.level.size())
        if (user.level[i] < 1 || user.level[i] > n)
            quitf(_wa, "Номера зон должны быть от 1 до %d, однако номер зоны города %d у участника равен %d", n, i + 1, user.level[i]);

    if (jury.outcome != "NO" && jury.outcome != "YES") {
        quitf(_fail, "jury answer incorrect: YES or NO expected, '%s' found", jury.outcome.c_str());
    }

    if (user.outcome != "NO" && user.outcome != "YES") {
        quitf(_pe, "Ожидалось YES или NO, найдено: '%s'", user.outcome.c_str());
    }

    if (!check_answer(jury)) {
        quitf(_fail, "В решении жюри номера зон меняются не монотонно");
    }

    if (!check_answer(user)) {
        quitf(_wa, "Номера зон меняются не монотонно");
    }

    if (jury.outcome == "YES") {
        if (user.outcome == "NO")
            quitf(_wa, "Ответ участника NO, однако решение существует");
        else
            quitf(_ok, "Ответ YES, N = %d, M = %d, K = %d", n, m, k);
    } else {
        if (user.outcome == "YES")
            quitf(_fail, "Ответ существует, однако не найден жюри");
        else
            quitf(_ok, "Ответ NO, N = %d, M = %d, K = %d", n, m, k);
    }

    quitf(_fail, "???");
}
