import java.util.*;
public class tournamentmatchmaking_xiaowuc1_ff {
  static final int NUMP = 15;
  static final int SHIFT = 15;
  static final int MASK = (1<<SHIFT)-1;
  static int[][] roles;
  public static void main(String[] args) throws Exception {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    roles = new int[n][];
    int[] even = new int[n]; int evenc = 0;
    int[] odd = new int[n]; int oddc = 0;
    for(int i = 0; i < n; i++) {
      int k = sc.nextInt();
      roles[i] = new int[k];
      if(k%2==0) even[evenc++] = i;
      else odd[oddc++] = i;
      for(int a = 0; a < k; a++) {
        int x = sc.nextInt()-1;
        int y = sc.nextInt()-1;
        roles[i][a] = (x << SHIFT) | (y);
      }
    }
    int outersnk = (evenc+oddc+1);
    boolean[][] outer = new boolean[outersnk+1][outersnk+1];
    for(int i = 0; i < evenc; i++) outer[0][i+1] = true;
    for(int i = 0; i < oddc; i++) outer[1+evenc+i][outersnk] = true;
    for(int i = 0; i < evenc; i++) for(int j = 0; j < oddc; j++) {
      if(roles[even[i]].length + roles[odd[j]].length != NUMP) continue;
      boolean[][] inner = new boolean[2*NUMP+2][2*NUMP+2];
      for(int a = 0; a < NUMP; a++) inner[0][a+1] = true;
      for(int a = 0; a < NUMP; a++) inner[NUMP+1+a][2*NUMP+1] = true;
      int idx = 1;
      for(int a: roles[even[i]]) {
        inner[idx][NUMP+1+(a&MASK)] = true;
        inner[idx][NUMP+1+(a>>SHIFT)] = true;
        idx++;
      }
      for(int a: roles[odd[j]]) {
        inner[idx][NUMP+1+(a&MASK)] = true;
        inner[idx][NUMP+1+(a>>SHIFT)] = true;
        idx++;
      }
      if(ff(inner) == NUMP) outer[i+1][evenc+1+j] = true;
    }
    System.out.println(ff(outer));
  }
  // assume 0 is src and last is sink
  public static int ff(boolean[][] w) {
    if(w.length == 0) return 0;
    int[] seen = new int[w.length];
    int seeniter = 0;
    while(flow(w, 0, seen, ++seeniter));
    return seeniter-1;
  }
  public static boolean flow(boolean[][] g, int curr, int[] seen, int seeniter) {
    if(curr == g.length-1) return true;
    for(int i = 0; i < g[curr].length; i++) {
      if(g[curr][i] && seen[i] != seeniter) {
        seen[i] = seeniter;
        if(flow(g, i, seen, seeniter)) {
          g[curr][i] = false;
          g[i][curr] = true;
          return true;
        }
      }
    }
    return false;
  }
}
