import java.awt.Dimension;
import java.io.*;
import static java.
lang.
Math.
*; import java.math.BigDecimal.*;
import 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 {
}
boolean oj = true;
try {
oj
= System.
getProperty("MYLOCAL") == null; }
if (oj) {
} else {
try {
sc
= new FastScanner
(new FileReader("input.txt")); 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();
}
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;
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="FastScanner">
class FastScanner {
}
while (!st.hasMoreElements()) {
try {
return null;
}
}
return st.nextToken();
}
int nextInt() {
}
long nextLong() {
return Long.
parseLong(next
()); }
double nextDouble() {
return Double.
parseDouble(next
()); }
try {
return br.readLine();
return null;
}
}
}
//</editor-fold>
class Solver {
void myAssert(boolean OK) {
if (!OK) {
Ideone.MLE();
}
}
FastScanner sc;
class Rib{
int to, w;
Rib(int to, int w) {
this.to = to;
this.w = w;
}
}
int n;
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][];
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();
}
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() );
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[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;
}
}