/*--------------------------------------------------------------*/
/* ACM ICPC 2009-2010, NEERC                                    */
/* Northern Subregional Contest                                 */
/* St Petersburg, October 17, 2009                              */
/*--------------------------------------------------------------*/
/* Problem K. Kripke Model                                      */
/*                                                              */
/* Original idea         Fedor Tsarev                           */
/* Problem statement     Fedor Tsarev                           */
/* Testset               Fedor Tsarev                           */
/*--------------------------------------------------------------*/
/* Solution                                                     */
/*                                                              */
/* Author                Georgiy Korneev                        */
/*--------------------------------------------------------------*/
 
import java.util.*;
import java.io.*;

public class kripke_gk implements Runnable {
    static Reader in;
    static PrintWriter out;
    
    static final int MAX_N = 100000;
    static final int MAX_M = 100000;
    static final int MAX_K = 26;
    
    boolean[][] ap;
    List<Set<Integer>> edges;
    boolean[] g;
    boolean[] e;
    int a;
    int b;

    int nextInt() {
        try {
            int ch = in.read();
            while (ch < '0') {
                ch = in.read();
            }
            int result = 0;
            while (ch >= '0') {
                result = result * 10 + ch - '0';
                ch = in.read();
            }
            return result;
        } catch (IOException e) {
            throw new AssertionError(e);
        }
    }

    String nextWord() {
        try {
            int ch = in.read();
            while (ch <= ' ') {
                ch = in.read();
            }
            StringBuilder sb = new StringBuilder();
            while (ch > ' ') {
                sb.append((char) ch);
                ch = in.read();
            }
            return sb.toString();
        } catch (IOException e) {
            throw new AssertionError(e);
        }
    }

    public void run() {
        int n = nextInt();
        int m = nextInt();
        int k = nextInt();
        
        ap = new boolean[n][k];
        for (int i = 0; i < n; i++) {
            int c = nextInt();
            for (int j = 0; j < c; j++) {
                ap[i][nextWord().charAt(0) - 'a'] = true;
            }
        }

        edges = new ArrayList<Set<Integer>>();
        for (int i = 0; i < n; i++) {
            Set<Integer> es = new HashSet<Integer>();
            es.add(i);
            edges.add(es);
        }
        
        for (int i = 0; i < m; i++) {
            int f = nextInt();
            int t = nextInt();
            edges.get(t - 1).add(f - 1);
        }
        
        String query = nextWord();
        a = query.charAt(2) - 'a';
        b = query.charAt(7) - 'a';
        
        g = new boolean[n];
        for (int i = 0; i < n; i++) {
            if (!ap[i][b]) {
                dfsG(i);
            }
        }
        
        e = new boolean[n];
        for (int i = 0; i < n; i++) {
            if (!g[i]) {
                dfsE(i);
            }
        }
        
        int c = 0;
        for (int i = 0; i < n; i++) {
            if (e[i]) {
                c++;
            }
        }

        out.println(c);
        for (int i = 0; i < n; i++) {
            if (e[i]) {
                out.println((i + 1));
            }
        }
    }

    void dfsG(int v) {
        if (!g[v]) {
            g[v] = true;
            for (int t : edges.get(v)) {
                dfsG(t);
            }
        }
    }

    void dfsE(int v) {
        if (!e[v]) {
            if (!g[v] || ap[v][a]) {
                e[v] = true;
                for (int t : edges.get(v)) {
                    dfsE(t);
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {        
        in = new BufferedReader(new FileReader("kripke.in"));
        out = new PrintWriter("kripke.out");

        new kripke_gk().run();

        in.close();
        out.close();
    }
}
