/*--------------------------------------------------------------*/
/* 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                Andrew Stankevich                      */
/*--------------------------------------------------------------*/
 
import java.io.*;
import java.util.*;

class kripke_as implements Runnable {
    ArrayList<Integer>[] to;
    ArrayList<Integer>[] fr;

    boolean[] vis;
    int[] torder;
    int tpos;

    int[] color;

    ArrayList<Integer>[] comp;

    void dfs(int x) {
        vis[x] = true;
        for (int y : to[x]) {
            if (!vis[y]) {
                dfs(y);
            }
        }
        torder[--tpos] = x;
    }

    void dfs2(int x, int c) {
        vis[x] = true;
        color[x] = c;
        for (int y : fr[x]) {
            if (!vis[y]) {
                dfs2(y, c);
            }
        }
    }

    public void solve() throws IOException {
        MyScanner in = new MyScanner(new File("kripke.in"));
        PrintWriter out = new PrintWriter(new File("kripke.out"));

        int n = in.nextInt();
        int m = in.nextInt();
        int nlet = in.nextInt();
        boolean[][] h = new boolean[n][nlet];
        to = new ArrayList[n];
        fr = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            int kk = in.nextInt();
            for (int j = 0; j < kk; j++) {
                char c = in.next().charAt(0);
                h[i][c - 'a'] = true;
            }
            to[i] = new ArrayList<Integer>();
            fr[i] = new ArrayList<Integer>();
        }

        for (int i = 0; i < m; i++) {
            int s = in.nextInt() - 1;
            int t = in.nextInt() - 1;
            to[s].add(t);
            fr[t].add(s);
        }

        vis = new boolean[n];
        torder = new int[n];
        tpos = n;
        for (int i = 0; i < n; i++) {
            if (!vis[i]) {
                dfs(i);
            }
        }

        Arrays.fill(vis, false);
        int cn = 0;
        color = new int[n];
        for (int i = 0; i < n; i++) {
            if (!vis[torder[i]]) {
                dfs2(torder[i], cn++);
            }
        }

        comp = new ArrayList[cn];
        for (int i = 0; i < cn; i++) {
            comp[i] = new ArrayList<Integer>();
        }
        for (int i = 0; i < n; i++) {
            comp[color[i]].add(i);
        }

        String z = in.next();
        int a = z.charAt(2) - 'a';
        int b = z.charAt(7) - 'a';

        boolean[] allVB = new boolean[cn];
        Arrays.fill(allVB, true);
        for (int i = 0; i < n; i++) {
            if (!h[i][b]) {
                allVB[color[i]] = false;
            }
        }

        boolean[] allPB = allVB.clone();
        for (int i = cn - 1; i >= 0; i--) {
            if (!allVB[i]) {
                continue;
            }

            search:
            for (int j : comp[i]) {
                for (int k : to[j]) {
                    if (!allPB[color[k]]) {
                        allPB[i] = false;
                        break search;
                    }
                }
            }
        }

        Queue<Integer> q = new ArrayDeque<Integer>();
        Arrays.fill(vis, false);
        for (int i = 0; i < n; i++) {
            if (allPB[color[i]]) {
                q.add(i);
                vis[i] = true;
            }
        }

        int ans = 0;
        while (q.size() > 0) {
            ans++;
            int x = q.poll();
            for (int y : fr[x]) {
                if (!vis[y] && h[y][a]) {
                    vis[y] = true;
                    q.add(y);
                }
            }
        }

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

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

    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
            throw new AssertionError();
        }
    }

    static class MyScanner extends BufferedReader {
        MyScanner(File name) throws FileNotFoundException {
            super(new FileReader(name));
        }

        StringTokenizer st;

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(readLine());
                } catch (IOException e) {
                    throw new AssertionError(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
    }

    public static void main(String[] args) {
        new Thread(new kripke_as()).start();
    }
}
