/*--------------------------------------------------------------*/
/* 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                Fedor Tsarev                           */
/*--------------------------------------------------------------*/
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;


public class kripke_ft_arrays implements Runnable {

	private static final int MAX_N = 10000;
	private static final int MAX_M = 100000;
	private static final int MAX_K = 26;
	private BufferedReader in;
	private StringTokenizer st;
	private PrintWriter out;
	int[][] gInv;

	public kripke_ft_arrays() throws IOException {
		in = new BufferedReader(new FileReader(new File("kripke.in")));
		st = new StringTokenizer("");
		out = new PrintWriter(new FileWriter(new File("kripke.out")));
	}
	
	public static void main(String[] args) throws IOException {
		new Thread(new kripke_ft_arrays()).start();
	}
	
	public void run() {
		try {
			solve();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		} finally { 
			out.close();
		}
	}

	private String nextToken() throws IOException {
		while (!st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}
	
	private int nextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(nextToken());
	}

	private void solve() throws NumberFormatException, IOException {
		long t0 = System.currentTimeMillis();
		int n = nextInt();
//		checkBounds(n, 1, MAX_N, "n");
		int m = nextInt();
//		checkBounds(m, 0, MAX_M, "m");
		int k = nextInt();
//		checkBounds(k, 1, MAX_K, "k");
		char[][] ap = new char[n][];
		for (int i = 0; i < n; i++) {
			int c = nextInt();
//			checkBounds(c, 0, k, "c[" + (i + 1) + "]");
			ap[i] = new char[c];
			for (int j = 0; j < c; j++) {
				String s = nextToken();
//				myAssert(s.length() == 1, "Atomic proposition is not a character: state" + (i + 1) + ", proposition: " + s);
				char ch = s.charAt(0);
//				myAssert(('a' <= ch) && (ch < (char) ('a' + k)), "Illegal name of atomic proposition : state" + (i + 1) + ", proposition: " + s + " (k = " + k + ")");
				ap[i][j] = s.charAt(0);
			}
		}
		int[][] transitions = new int[m + n][];
		for (int i = 0; i < m; i++) {
			int s = nextInt();
//			checkBounds(s, 1, n, "s[" + (i + 1) + "]");
			int t = nextInt();
//			checkBounds(t, 1, n, "t[" + (i + 1) + "]");
//			myAssert(s != t, "Transition #" + (i + 1) + " is a loop");
			transitions[i] = new int[] {s - 1, t - 1};
		}
		for (int i = 0; i < n; i++) {
			transitions[m + i] = new int[] {i, i};
		}
		String formula = nextToken();

		System.out.println(t0 - System.currentTimeMillis());

		char x = formula.charAt(2);
		char y = formula.charAt(7);
		boolean[] hasY = new boolean[n];
		boolean[] hasX = new boolean[n];
		for (int i = 0; i < n; i++) {
			for (char ch : ap[i]) {
				if (ch == x) {
					hasX[i] = true;
				}
				if (ch == y) {
					hasY[i] = true;
				}
			}
		}
		int[] degInv = new int[n];
		for (int[] t : transitions) {
			degInv[t[1]]++;
		}
		gInv = new int[n][];
		for (int i = 0; i < n; i++) {
			gInv[i] = new int[degInv[i]];
			degInv[i] = 0;
		}
		
		for (int[] t : transitions) {
			gInv[t[1]][degInv[t[1]]++] = t[0];
		}
		
		boolean[] isNotAGy = new boolean[n];
		
		for (int i = 0; i < n; i++) {
			if (!isNotAGy[i] && !hasY[i]) {
				dfs1(i, isNotAGy);
			}
		}
		
		boolean[] w = new boolean[n];
		for (int i = 0; i < n; i++) {
			if (!isNotAGy[i] && !w[i]) {
				dfs2(i, w, hasX);
			}
		}
		
		boolean[] ans = new boolean[n];
		for (int i = 0; i < n; i++) {
			ans[i] = w[i] || (!isNotAGy[i]);
		}
		int cnt = 0;
		for (int i = 0; i < n; i++) {
			if (ans[i]) {
				cnt++;
			}
		}
		
		out.println(cnt);
		for (int i = 0; i < n; i++) {
			if (ans[i]) {
				out.println(i + 1);
			}
		}
		
	}

	private void dfs1(int u, boolean[] w) {
		w[u] = true;
		for (int v : gInv[u]) {
			if (!w[v]) {
				dfs1(v, w);
			}
		}
	}

	private void dfs2(int u, boolean[] w, boolean[] valid) {
		w[u] = true;
		for (int v : gInv[u]) {
			if (!w[v] && valid[v]) {
				dfs2(v, w, valid);
			}
		}
	}
	
}
