import java.awt.Dimension;
import java.io.*;
import static java.lang.Character.*;
import static java.lang.Math.*;
import java.math.BigDecimal.*;
import java.math.BigInteger.*;
import static java.math.BigInteger.*;
import java.util.*;
import static java.util.Arrays.*;


//<editor-fold defaultstate="collapsed" desc="Main">
class Ideone {
    // https://n...content-available-to-author-only...s.org/kb/73/java/editor-codereference_ru.html#display

    private void run() {
        try {
            Locale.setDefault(Locale.US);
        } catch (Exception e) {
        }
        boolean oj = true;
        try {
            oj = System.getProperty("MYLOCAL") == null;
        } catch (Exception e) {
        }

        if (oj) {
            sc = new FastScanner(new InputStreamReader(System.in));
            out = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            try {
                sc = new FastScanner(new FileReader("input.txt"));
                out = new PrintWriter(new FileWriter("output.txt"));
            } catch (IOException e) {
                MLE();
            }
        }
        Solver s = new Solver();
        s.sc = sc;
        s.out = out;
        s.solve();
        if (!oj) {
            err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
            err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        }
        out.flush();
    }

    private void show(int[] arr) {
        for (int v : arr) {
            err.print(" " + v);
        }
        err.println();
    }

    public static void exit() {
        err.println("Time: " + (System.currentTimeMillis() - timeBegin) / 1e3);
        err.printf("Mem: %d\n", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20);
        out.flush();
        out.close();
        System.exit(0);
    }

    public static void MLE() {
        int[][] arr = new int[1024 * 1024][];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new int[1024 * 1024];
        }
    }

    public static void main(String[] args) {
        new Ideone().run();
    }

    static long timeBegin = System.currentTimeMillis();
    static FastScanner sc;
    static PrintWriter out;
    static PrintStream err = System.err;
}
    //</editor-fold>

//<editor-fold defaultstate="collapsed" desc="FastScanner">
class FastScanner {

    BufferedReader br;
    StringTokenizer st;

    FastScanner(InputStreamReader reader) {
        br = new BufferedReader(reader);
        st = new StringTokenizer("");
    }

    String next() {
        while (!st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception ex) {
                return null;
            }
        }
        return st.nextToken();
    }

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

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        try {
            return br.readLine();
        } catch (IOException ex) {
            return null;
        }
    }
}
//</editor-fold>

class Solver {

    void myAssert(boolean OK) {
        if (!OK) {
            Ideone.MLE();
        }
    }

    FastScanner sc;
    PrintWriter out;
    static PrintStream err = System.err;

    class Rib{
        int to, w;
        
        Rib(int to, int w) {
            this.to = to;
            this.w = w;
        }
    }
    
    int n;
    String[] place;
    int[][] person;
    ArrayList<Rib>[] gr;    
    int[] color;
    TreeSet<Integer>[] comp;
    
    void dfs( int v ){
        comp[color[v]].add(v);
        for( Rib r : gr[v] ){
            if( color[r.to] == -1 ){
                color[r.to] = color[v] ^ r.w;
                dfs( r.to );
            }
            myAssert( color[r.to] == (color[v] ^ r.w) );
        }
    }
    
    void solve() {
        n = sc.nextInt();
        person = new int[n+1][];
        place = new String[n+1];
        for( int v = 1; v <= n; ++v ){
            place[v] = sc.next();
            person[v] = new int[sc.nextInt()];
            for (int j = 0; j < person[v].length; j++)
                person[v][j] = sc.nextInt();
        }

        gr = new ArrayList[n+1];
        for (int v = 1; v <= n; v++)
            gr[v] = new ArrayList<>();
        
       
        for( int v = 1; v <= n; ++v ){
            for( int to : person[v] ){
                if( place[v].equals(place[to]) ){
                    gr[v ].add(new Rib(to, 0));
                    gr[to].add(new Rib( v, 0));
                }
                else{
                    gr[v ].add(new Rib(to, 1));
                    gr[to].add(new Rib( v, 1));
                }
            }
        }
        
        TreeSet<Integer> ans  = getAns();
        
        out.println( ans.size() );
        for (Integer v : ans) {
            out.print( " " + v );
            myAssert( 1 <= v && v <= n );
        }
        out.println();
    } 

    TreeSet<Integer> getAns() {
        TreeSet<Integer> ans = new TreeSet<>();
        color = new int[n+1];
        fill( color, -1 );
        //int cntUsedVertex = 0;
        for (int v = 1; v <= n; v++) {
            if( color[v] == -1 ){
                color[v] = 0;
                comp = new TreeSet[2];
                comp[0] = new TreeSet<>();
                comp[1] = new TreeSet<>();
                dfs( v );
                //cntUsedVertex += comp[0].size() + comp[1].size();
                if( comp[0].size() <= comp[1].size() )
                    ans.addAll(comp[0]);
                else
                    ans.addAll(comp[1]);
            }
        }
        //myAssert( cntUsedVertex == n );
        if( ans.isEmpty() ) ans.add(1);
        return ans;
    }

}