Problem: Isaac H. Ives attended an international student party and made a lot of girl friends (as many other persons expected). To strike up a good friendship with them, he decided to have dates with them. However, it is hard for him to schedule dates because he made so many friends. Thus he decided to find the best schedule using a computer program. The most important criterion in scheduling is how many different girl friends he will date. Of course, the more friends he will date, the better the schedule is. However, though he has the ability to write a program finding the best schedule, he doesn’t have enough time to write it.

Your task is to write a program to find the best schedule instead of him.



Input

The input consists of a series of data sets. The first line of each data set contains a single positive integer N (N ≤ 1,000) that represents the number of persons Isaac made friends with in the party. The next line gives Isaac’s schedule, followed by N lines that give his new friends’ schedules. Each schedule consists of a positive integer M that represents the number of available days followed by M positive integers each of which represents an available day.

The input is terminated by a line that contains a single zero. This is not part of data sets and should not be processed.

Output

For each data set, print a line that contains the maximum number of girl friends Isaac can have dates with.

Example

Input

3
3 1 3 5
2 1 4
4 1 2 3 6
1 3
0


Output

2

Solution (in CPP):

Solution:
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 3000


//辺を表す構造体(行先、容量、逆辺のインデックス)
struct Edge{
	Edge(int arg_to,int arg_capacity,int arg_rev_index){
		to = arg_to;
		capacity = arg_capacity;
		rev_index = arg_rev_index;
	}
	int to,capacity,rev_index;
};

int V,E;
int N;
map<int,int> MAP;
vector<Edge> G[NUM]; //グラフの隣接リスト表現
int dist[NUM]; //sourceからの距離
int cheked_index[NUM]; //どこまで調べ終わったか

//fromからtoへ向かう容量capacityの辺をグラフに追加する
void add_edge(int from,int to,int capacity){
	G[from].push_back(Edge(to,capacity,G[to].size()));
	G[to].push_back(Edge(from,0,G[from].size()-1)); //逆辺の、初期容量は0
}

//sourceからの最短距離をBFSで計算する
void bfs(int source){
	for(int i = 0; i < V; i++)dist[i] = -1;
	queue<int> Q;
	dist[source] = 0;
	Q.push(source);

	while(!Q.empty()){
		int node_id = Q.front();
		Q.pop();
		for(int i = 0; i < G[node_id].size(); i++){
			Edge &e = G[node_id][i];
			if(e.capacity > 0 && dist[e.to] < 0){ //辺の容量が正で、かつエッジの行先に未訪問の場合
				dist[e.to] = dist[node_id]+1;
				Q.push(e.to);
			}
		}
	}
}

//増加パスをDFSで探す
int dfs(int node_id,int sink,int flow){
	if(node_id == sink)return flow; //終点についたらflowをreturn

	for(int &i = cheked_index[node_id]; i < G[node_id].size(); i++){ //node_idから出ているエッジを調査
		Edge &e = G[node_id][i];
		if(e.capacity > 0 && dist[node_id] < dist[e.to]){ //流せる余裕があり、かつsourceからの距離が増加する方法である場合
			int tmp_flow = dfs(e.to,sink,min(flow,e.capacity)); //流せるだけ流す
			if(tmp_flow > 0){ //流せた場合
				e.capacity -= tmp_flow; //流した分、エッジの容量を削減する
				G[e.to][e.rev_index].capacity += tmp_flow; //逆辺の容量を、流した分だけ増加させる
				return tmp_flow;
			}
		}
	}
	return 0;
}


//sourceからsinkへの最大流を求める
int max_flow(int source,int sink){ //source:始点 sink:終点
	int flow = 0,add;
	while(true){ //増加パスが存在する限り、流量を追加し続ける
		bfs(source);
		if(dist[sink] < 0)break; //sourceからsinkへと辿り着く残余グラフがない、つまり増加パスが無くなった場合、break
		for(int i = 0; i < V; i++)cheked_index[i] = 0;
		while((add = dfs(source,sink,BIG_NUM)) > 0){ //増加パスが見つかる間、加算
			flow += add;
		}
	}
	return flow;
}

void func(){

	MAP.clear();
	for(int i = 0; i < NUM; i++)G[i].clear();

	int num,tmp,index = 2;
	scanf("%d",&num);

	int source = 0,sink = 1;

	for(int loop = 0; loop < num; loop++){
		scanf("%d",&tmp);
		MAP[tmp] = index;
		add_edge(source,index,1); //sourceからindexに、容量1の辺を張る
		index++;
	}

	int integrate;

	for(int loop = 0; loop < N; loop++){
		scanf("%d",&num);
		add_edge(index,sink,1); //1人の人物につき、最大流量1の集約路を張る
		integrate = index;
		index++;

		for(int i = 0; i < num; i++){
			scanf("%d",&tmp);
			auto at = MAP.find(tmp);
			if(at == MAP.end())continue; //Isaccの都合の良い日でなければ無視
			add_edge(MAP[tmp],integrate,1); //Isaccの都合の良い日から、
		}
	}

	V = index;

	printf("%d\n", max_flow(source,sink));
}


int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}