/*--------------------------------------------------------------*/
/* 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;
import java.util.HashSet;

public class kripke_ft 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;
	private ArrayList<ArrayList<Integer>> g;
	private ArrayList<ArrayList<Integer>> gInv;

	public kripke_ft() 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()).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 myAssert(boolean u, String message) {
		if (!u) {
			throw new Error("Assertion failed!!! " + message);
		}
	}


	class Pair {
		int a;
		int b;

		public Pair(int a, int b) {
			this.a = a;
			this.b = b;
		}

		public int hashCode() {
			return a + 239 * b;
		}

		public boolean equals(Object o) {
			Pair p = (Pair) o;
			return a == p.a && b == p.b;
		}
	}
	
	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);
			}
		}
		HashSet<Pair> set = new HashSet<Pair>();
		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};
			Pair p = new Pair(s - 1, t - 1);
			myAssert(!set.contains(p), "Duplicated transition: " + s + " " + t);
			set.add(p);
		}
		for (int i = 0; i < n; i++) {
			transitions[m + i] = new int[] {i, i};
		}
		String formula = nextToken();

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

		checkFormula(formula, k);
		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;
				}
			}
		}
		g = new ArrayList<ArrayList<Integer>>();
		gInv = new ArrayList<ArrayList<Integer>>();
		for (int i = 0; i < n; i++) {
			g.add(new ArrayList<Integer>());
			gInv.add(new ArrayList<Integer>());
		}
		
		for (int[] t : transitions) {
			g.get(t[0]).add(t[1]);
			gInv.get(t[1]).add(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.get(u)) {
			if (!w[v]) {
				dfs1(v, w);
			}
		}
	}

	private void dfs2(int u, boolean[] w, boolean[] valid) {
		w[u] = true;
		for (int v : gInv.get(u)) {
			if (!w[v] && valid[v]) {
				dfs2(v, w, valid);
			}
		}
	}
	
	private void checkFormula(String formula, int k) {
		String message = "Formula is invalid: '" + formula + "' (k = " + k + ")";
		// E(xU(AGy))

		myAssert(formula.length() == "E(xU(AGy))".length(), message);
		myAssert(formula.charAt(0) == 'E', message);
		myAssert(formula.charAt(1) == '(', message);
		{
			char ch = formula.charAt(2);
			myAssert(('a' <= ch) && (ch < (char) ('a' + k)), "Illegal name of atomic proposition : formula '" + formula + "', proposition: " + ch + " (k = " + k + ")");
		}
		
		myAssert(formula.charAt(3) == 'U', message);
		myAssert(formula.charAt(4) == '(', message);
		myAssert(formula.charAt(5) == 'A', message);
		myAssert(formula.charAt(6) == 'G', message);
		
		{
			char ch = formula.charAt(7);
			myAssert(('a' <= ch) && (ch < (char) ('a' + k)), "Illegal name of atomic proposition : formula '" + formula + "', proposition: " + ch + " (k = " + k + ")");
		}
		myAssert(formula.charAt(8) == ')', message);
		myAssert(formula.charAt(9) == ')', message);
	}

	private void checkBounds(int x, int min, int max, String name) {
		myAssert((min <= x) && (x <= max), name + " is out of bounds: min = " + min + ", max = " + max + ", " + name + " = " + x);
	}

}
