#include <functional>

#include <algorithm>

#include <memory.h>

#include <string.h>

#include <ctype.h>

#include <stdio.h>

#include <bitset>

#include <string>

#include <vector>

#include <queue>

#include <stack>

#include <cmath>

#include <map>

#include <set>

using namespace std;

typedef long long INT;

typedef pair <int, int> pii;

typedef pair <int, pii> p3i;

#define NN 210

int val[3][3]={{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};

int cnt[NN], con[NN][NN], vst[NN], a[NN];

int n, res, tot;

void put(int c, int s) {

	if (s>=res) return ;

    int i, j, k, top=-1, ok;

	int tvst[NN];

    memcpy(tvst, vst, sizeof(vst));

    for (i=0; i<n; i++)

        if (cnt[i]==0 && !vst[i]) cnt[i]=top, top=i;

    ok=0;

    for (i=0; i<n; i++)

        if (top==-1) break ;

        else {

            j=top; top=cnt[top]; cnt[j]=0;

            if (a[j]==c) {

				vst[j]=1;

	            for (k=0; k<n; k++)

	                if (con[j][k] && (--cnt[k])==0) cnt[k]=top, top=k;

	            ok++;

			}

        }

    if (!ok) return ;

	for (i=0; i<n; i++) if (!vst[i]) break;

	if (i==n) {

		res=s;

		return ;

	}

    for (i=0; i<3; i++) {

    	if (i!=c) {

			put(i, s+val[c][i]);

		    memcpy(vst, tvst, sizeof(vst));

		}

    }

}

int main() {

 	int i, u, v, j, m;

	int tcnt[NN];

	scanf("%d ", &n);

	for (i=0; i<n; i++) scanf("%d ", &a[i]), a[i]--;

	memset(con, 0, sizeof(con));

	memset(cnt, 0, sizeof(cnt));

	for (i=0; i<n; i++) {

		for (scanf("%d ", &m); m--; ) {

			scanf("%d ", &j);

			j--;

            cnt[i]++; con[j][i]=1;

		}

	}

	res=1000000;

	memcpy(tcnt, cnt, sizeof(cnt));

	for (i=0; i<3; i++) {

		memset(vst, 0, sizeof(vst));

		memcpy(cnt, tcnt, sizeof(cnt));

		put(i, 0);

	}

	printf("%d\n", res+n);

    return 0;

}


#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>

using namespace std;
using namespace std::tr1;

typedef long long llong;
typedef pair<int, int> int2;
typedef pair<llong, llong> llong2;
#define foreach(v,c) for (typeof((c).begin()) v = (c).begin(); v != (c).end(); ++v)
#define rep(i,n) for (int i = 0; i < (n); ++i)

int cost(int a, int b) {
  if (a == 1 && b == 2 || a == 2 && b == 3 || a == 3 && b == 1) return 1;
  return 2;
}

int n;
static vector<int> c[3];
static int house[101];
static vector<int> dep[101];

int solve(int s) {
  int res = 0;
  int none = 0;
  static bool done[101];
  memset(done, 0, sizeof done);
  for (; none < 3; s = (s+1) % 3) {
    bool found = false;
    foreach(it, c[s]) {
      if (done[*it]) continue;
      bool can = true;
      foreach(it2, dep[*it])
        if (!done[*it2] && house[*it2] != house[*it]) { can = false; break; }
      if (!can) continue;
      done[*it] = true;
      found = true;
    }
    none = found ? 0 : (none + 1);
    ++res;
  }
  return res - 4;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin >> n;
  memset(c, 0, sizeof c);
  for (int i = 1; i <= n; ++i) {
    int h; cin >> h;
    c[h-1].push_back(i);
    house[i] = h;
  }

  for (int i = 1; i <= n; i++) {
    int k; cin >> k;
    for (int j = 0; j < k; j++) {
      int d; cin >> d;
      dep[i].push_back(d);
    }
  }

  cout << n + min(solve(0), min(solve(1), solve(2))) << endl;
}


#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>

using namespace std;
using namespace std::tr1;

typedef long long llong;
typedef pair<int, int> int2;
typedef pair<llong, llong> llong2;
#define foreach(v,c) for (typeof((c).begin()) v = (c).begin(); v != (c).end(); ++v)
#define rep(i,n) for (int i = 0; i < (n); ++i)

int cost(int a, int b) {
  if (a == 1 && b == 2 || a == 2 && b == 3 || a == 3 && b == 1) return 1;
  return 2;
}

int n;
static vector<int> c[3];
static int house[201];
static vector<int> dep[201];

int solve(int s) {
  int res = 0;
  int none = 0;
  static bool done[101];
  memset(done, 0, sizeof done);
  for (; none < 3; s = (s+1) % 3) {
    bool found = false;
    for (int i = 0; i < c[s].size(); i++) {
      foreach(it, c[s]) {
        if (done[*it]) continue;
        bool can = true;
        foreach(it2, dep[*it])
          if (!done[*it2]) { can = false; break; }
        if (!can) continue;
        done[*it] = true;
        found = true;
      }
    }
    none = found ? 0 : (none + 1);
    ++res;
  }
  return res - 4;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin >> n;
  memset(c, 0, sizeof c);
  for (int i = 1; i <= n; ++i) {
    int h; cin >> h;
    c[h-1].push_back(i);
    house[i] = h;
  }

  for (int i = 1; i <= n; i++) {
    int k; cin >> k;
    for (int j = 0; j < k; j++) {
      int d; cin >> d;
      dep[i].push_back(d);
    }
  }

  cout << n + min(solve(0), min(solve(1), solve(2))) << endl;
}


#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>

using namespace std;
using namespace std::tr1;

typedef long long llong;
typedef pair<int, int> int2;
typedef pair<llong, llong> llong2;
#define foreach(v,c) for (typeof((c).begin()) v = (c).begin(); v != (c).end(); ++v)
#define rep(i,n) for (int i = 0; i < (n); ++i)

int cost(int a, int b) {
  if (a == 1 && b == 2 || a == 2 && b == 3 || a == 3 && b == 1) return 1;
  return 2;
}

int n;
static vector<int> c[3];
static int house[101];
static vector<int> dep[101];

int solve(int s) {
  int res = 0;
  int none = 0;
  static bool done[101];
  memset(done, 0, sizeof done);
  for (; none < 3; s = (s+1) % 3) {
    bool found = false;
    for (int i = 0; i < c[s].size(); i++) {
      foreach(it, c[s]) {
        if (done[*it]) continue;
        bool can = true;
        foreach(it2, dep[*it])
          if (!done[*it2]) { can = false; break; }
        if (!can) continue;
        done[*it] = true;
        found = true;
      }
    }
    none = found ? 0 : (none + 1);
    ++res;
  }
  return res - 4;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin >> n;
  memset(c, 0, sizeof c);
  for (int i = 1; i <= n; ++i) {
    int h; cin >> h;
    c[h-1].push_back(i);
    house[i] = h;
  }

  for (int i = 1; i <= n; i++) {
    int k; cin >> k;
    for (int j = 0; j < k; j++) {
      int d; cin >> d;
      dep[i].push_back(d);
    }
  }

  cout << n + min(solve(0), min(solve(1), solve(2))) << endl;
}


#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>

using namespace std;
using namespace std::tr1;

typedef long long llong;
typedef pair<int, int> int2;
typedef pair<llong, llong> llong2;
#define foreach(v,c) for (typeof((c).begin()) v = (c).begin(); v != (c).end(); ++v)
#define rep(i,n) for (int i = 0; i < (n); ++i)

int cost(int a, int b) {
  if (a == 1 && b == 2 || a == 2 && b == 3 || a == 3 && b == 1) return 1;
  return 2;
}

int n;
static vector<int> c[3];
static int house[201];
static vector<int> dep[201];

int solve(int s) {
  int res = 0;
  int none = 0;
  static bool done[201];
  memset(done, 0, sizeof done);
  for (; none < 3; s = (s+1) % 3) {
    bool found = false;
    for (int i = 0; i < c[s].size(); i++) {
      foreach(it, c[s]) {
        if (done[*it]) continue;
        bool can = true;
        foreach(it2, dep[*it])
          if (!done[*it2]) { can = false; break; }
        if (!can) continue;
        done[*it] = true;
        found = true;
      }
    }
    none = found ? 0 : (none + 1);
    ++res;
  }
  return res - 4;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin >> n;
  memset(c, 0, sizeof c);
  for (int i = 1; i <= n; ++i) {
    int h; cin >> h;
    c[h-1].push_back(i);
    house[i] = h;
  }

  for (int i = 1; i <= n; i++) {
    int k; cin >> k;
    for (int j = 0; j < k; j++) {
      int d; cin >> d;
      dep[i].push_back(d);
    }
  }

  cout << n + min(solve(0), min(solve(1), solve(2))) << endl;
}


// Vishal Gupta IIIT-H

#include <bits/stdc++.h>
using namespace std;

#define sz(a) int((a).size())
#define all(c) c.begin(),c.end() //all elements of a container
#define rall(c) c.rbegin(),c.rend()
#define tr(container,it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++) //traversing a container..works for any type of container
#define present(container, element) (container.find(element) != container.end())    //used for set...return 1 if el is ps 0 otherwise
#define cpresent(container, element) (find(all(container),element) != container.end())  //same as present...but is for vectors
#define INF		INT_MAX
#define FOR(i,a,b) 	for(int  i= (int )a ; i < (int )b ; ++i)
#define rep(i,n) 	FOR(i,0,n)
#define FORD(i,a,b) for( i = (a); i>= (int) b; i--)
#define si(n) scanf("%d",&n)
#define pi(n) printf("%d ",n)
#define pil(n) printf("%d\n",n)
#define piL(n) printf("%lld ",n)
#define piLL(n) printf("%lld\n",n)
#define sl(n) scanf("%lld",&n)
#define sd(n) scanf("%lf",&n)
#define ss(n) scanf("%s",n)
#define PB push_back
#define MP make_pair
#define scan(v,n)	vector<int> v;rep(i,n){ int j;si(j);v.PB(j);}
#define fill(a,b) memset(a,b,sizeof(a))
#define mod (int)(1e9 + 7)
#define pn printf("\n")
#define F first
#define S second
typedef long long int LL;
typedef vector <int> VI;
typedef pair < int ,int > PII;
typedef vector < PII > VPII;
template<class T>inline T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> inline T LCM(T a,T b){if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/gcd(a,b));}
VI g[300];
int c[300],cnt[300];
queue <int> q[3];
int main()
{
      int n,t,u,ans=0,tot=0;
      cin >> n;
      rep(i,n) cin >> c[i];
      rep(i,n){
      	cin >> t;
      		cnt[i]=t;
      		rep(j,t){
      			cin >> u;
      			g[u-1].PB(i);
      		}
      }
      int start;
      rep(i,n) if(cnt[i]==0) {
      	q[c[i]-1].push(i);
      	cnt[i]--;
      	//start=c[i]-1;
      }
	  VI f;
	  for(int i=2; i>=0; i--) if(!q[i].empty()){ start=i; f.PB(i); }
	  if(sz(f)==2 && f[0]==2 && f[1]==0) start=2;
	  while(true){
	  		while(!q[start].empty()){
	  			int top=q[start].front();
	  			q[start].pop();
	  			cnt[top]=-1;
	  			tot++;
	  			if(tot==n) {pil(ans+n); return 0;}
	  			rep(i,sz(g[top]))
	  			{
	  				cnt[g[top][i]]--;
	  			}
	  			rep(i,n) if(cnt[i]==0) { q[c[i]-1].push(i); cnt[i]--;}
	  		}
	  		start=(start+1)%3;
	  		ans++;
	  }
	  return 0;
}


// Vishal Gupta IIIT-H

#include <bits/stdc++.h>
using namespace std;

#define sz(a) int((a).size())
#define all(c) c.begin(),c.end() //all elements of a container
#define rall(c) c.rbegin(),c.rend()
#define tr(container,it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++) //traversing a container..works for any type of container
#define present(container, element) (container.find(element) != container.end())    //used for set...return 1 if el is ps 0 otherwise
#define cpresent(container, element) (find(all(container),element) != container.end())  //same as present...but is for vectors
#define INF		INT_MAX
#define FOR(i,a,b) 	for(int  i= (int )a ; i < (int )b ; ++i)
#define rep(i,n) 	FOR(i,0,n)
#define FORD(i,a,b) for( i = (a); i>= (int) b; i--)
#define si(n) scanf("%d",&n)
#define pi(n) printf("%d ",n)
#define pil(n) printf("%d\n",n)
#define piL(n) printf("%lld ",n)
#define piLL(n) printf("%lld\n",n)
#define sl(n) scanf("%lld",&n)
#define sd(n) scanf("%lf",&n)
#define ss(n) scanf("%s",n)
#define PB push_back
#define MP make_pair
#define scan(v,n)	vector<int> v;rep(i,n){ int j;si(j);v.PB(j);}
#define fill(a,b) memset(a,b,sizeof(a))
#define mod (int)(1e9 + 7)
#define pn printf("\n")
#define F first
#define S second
typedef long long int LL;
typedef vector <int> VI;
typedef pair < int ,int > PII;
typedef vector < PII > VPII;
template<class T>inline T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> inline T LCM(T a,T b){if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/gcd(a,b));}
VI g[300];
int c[300],cnt[300];
queue <int> q[3];
int main()
{
      int n,t,u,ans=0,tot=0;
      cin >> n;
      rep(i,n) cin >> c[i];
      rep(i,n){
      	cin >> t;
      		cnt[i]=t;
      		rep(j,t){
      			cin >> u;
      			g[u-1].PB(i);
      		}
      }
      int start;
      rep(i,n) if(cnt[i]==0) {
      	q[c[i]-1].push(i);
      	start=c[i]-1;
      }
	  while(true){
	  		while(!q[start].empty()){
	  			int top=q[start].front();
	  			q[start].pop();
	  			cnt[top]=-1;
	  			tot++;
	  			if(tot==n) {pil(ans+n); return 0;}
	  			rep(i,sz(g[top]))
	  			{
	  				cnt[g[top][i]]--;
	  			}
	  			rep(i,n) if(cnt[i]==0) { q[c[i]-1].push(i); cnt[i]--;}
	  		}
	  		start=(start+1)%3;
	  		ans++;
	  }
	  return 0;
}


// Vishal Gupta IIIT-H

#include <bits/stdc++.h>
using namespace std;

#define sz(a) int((a).size())
#define all(c) c.begin(),c.end() //all elements of a container
#define rall(c) c.rbegin(),c.rend()
#define tr(container,it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++) //traversing a container..works for any type of container
#define present(container, element) (container.find(element) != container.end())    //used for set...return 1 if el is ps 0 otherwise
#define cpresent(container, element) (find(all(container),element) != container.end())  //same as present...but is for vectors
#define INF		INT_MAX
#define FOR(i,a,b) 	for(int  i= (int )a ; i < (int )b ; ++i)
#define rep(i,n) 	FOR(i,0,n)
#define FORD(i,a,b) for( i = (a); i>= (int) b; i--)
#define si(n) scanf("%d",&n)
#define pi(n) printf("%d ",n)
#define pil(n) printf("%d\n",n)
#define piL(n) printf("%lld ",n)
#define piLL(n) printf("%lld\n",n)
#define sl(n) scanf("%lld",&n)
#define sd(n) scanf("%lf",&n)
#define ss(n) scanf("%s",n)
#define PB push_back
#define MP make_pair
#define scan(v,n)	vector<int> v;rep(i,n){ int j;si(j);v.PB(j);}
#define fill(a,b) memset(a,b,sizeof(a))
#define mod (int)(1e9 + 7)
#define pn printf("\n")
#define F first
#define S second
typedef long long int LL;
typedef vector <int> VI;
typedef pair < int ,int > PII;
typedef vector < PII > VPII;
template<class T>inline T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> inline T LCM(T a,T b){if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/gcd(a,b));}
VI g[300];
int c[300],cnt[300],sav[300];
queue <int> q[3];
int main()
{
      int n,t,u,ans=0,tot=0,mini=mod;
      cin >> n;
      rep(i,n) cin >> c[i];
      rep(i,n){
      	cin >> t;
      		cnt[i]=t;
      		sav[i]=t;
      		rep(j,t){
      			cin >> u;
      			g[u-1].PB(i);
      		}
      }

      for(int k=0; k< 3; k++){
		      rep(i,n) cnt[i]=sav[i];
		      rep(i,n) if(cnt[i]==0) {
		      	q[c[i]-1].push(i);
		      	cnt[i]--;
		      }
			  int start=k;
			  ans=0; tot=0;
			  while(true){
			  		while(!q[start].empty()){
			  			int top=q[start].front();
			  			q[start].pop();
			  			cnt[top]=-1;
			  			tot++;
			  			if(tot==n) {	mini=min(ans+n,mini); break;}
			  			rep(i,sz(g[top]))
			  			{
			  				cnt[g[top][i]]--;
			  			}
			  			rep(i,n) if(cnt[i]==0) { q[c[i]-1].push(i); cnt[i]--;}
			  		}
			  		if(tot==n) break;
			  		start=(start+1)%3;
			  		ans++;
			  }
	  	}
	  pil(mini);
	  return 0;
}


// Vishal Gupta IIIT-H

#include <bits/stdc++.h>
using namespace std;

#define sz(a) int((a).size())
#define all(c) c.begin(),c.end() //all elements of a container
#define rall(c) c.rbegin(),c.rend()
#define tr(container,it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++) //traversing a container..works for any type of container
#define present(container, element) (container.find(element) != container.end())    //used for set...return 1 if el is ps 0 otherwise
#define cpresent(container, element) (find(all(container),element) != container.end())  //same as present...but is for vectors
#define INF		INT_MAX
#define FOR(i,a,b) 	for(int  i= (int )a ; i < (int )b ; ++i)
#define rep(i,n) 	FOR(i,0,n)
#define FORD(i,a,b) for( i = (a); i>= (int) b; i--)
#define si(n) scanf("%d",&n)
#define pi(n) printf("%d ",n)
#define pil(n) printf("%d\n",n)
#define piL(n) printf("%lld ",n)
#define piLL(n) printf("%lld\n",n)
#define sl(n) scanf("%lld",&n)
#define sd(n) scanf("%lf",&n)
#define ss(n) scanf("%s",n)
#define PB push_back
#define MP make_pair
#define scan(v,n)	vector<int> v;rep(i,n){ int j;si(j);v.PB(j);}
#define fill(a,b) memset(a,b,sizeof(a))
#define mod (int)(1e9 + 7)
#define pn printf("\n")
#define F first
#define S second
typedef long long int LL;
typedef vector <int> VI;
typedef pair < int ,int > PII;
typedef vector < PII > VPII;
template<class T>inline T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> inline T LCM(T a,T b){if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/gcd(a,b));}
VI g[300];
int c[300],cnt[300];
queue <int> q[3];
int main()
{
      int n,t,u,ans=0,tot=0;
      cin >> n;
      rep(i,n) cin >> c[i];
      rep(i,n){
      	cin >> t;
      		cnt[i]=t;
      		rep(j,t){
      			cin >> u;
      			g[u-1].PB(i);
      		}
      }
      int start;
      rep(i,n) if(cnt[i]==0) {
      	q[c[i]-1].push(i);
      	start=c[i]-1;
      }
	  while(true){
	  		while(!q[start].empty()){
	  			int top=q[start].front();
	  			q[start].pop();
	  			cnt[top]=-1;
	  			tot++;
	  			if(tot==n) {pil(ans+n); return 0;}
	  			rep(i,sz(g[top]))
	  				{cnt[g[top][i]]--; }
	  			rep(i,n) if(cnt[i]==0) q[c[i]-1].push(i);
	  		}
	  		start=(start+1)%3;
	  		ans++;
	  }
	  return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>

using namespace std;

int comp[222], n, before[222], k;
vector<int> dpnd[222];

int solve(int curr) {
  int bfr[222], done = 0, ret = 0;
  for (int i = 1; i <= n; ++i)
    bfr [i] = before[i];
  vector<int> nodp[4];
  for (int i = 1; i <= n; ++i) if (before[i] == 0) nodp[comp[i]].push_back(i);
  while (done < n) {
    for (int i = 0; i < nodp[curr].size(); ++i) {
      int idx = nodp[curr][i];
      for (int j = 0; j < dpnd[idx].size(); ++j) {
        int idx2 = dpnd[idx][j];
        bfr[idx2]--;
        if (bfr[idx2] == 0) nodp[comp[idx2]].push_back(idx2);
      }
    }
    ret += nodp[curr].size();
    done += nodp[curr].size();
    nodp[curr].clear();
    if (done == n) break;
    ret++;
    curr++;
    if (curr == 4) curr = 1;
  }
  return ret;
}

int main() {
  cin >> n;
  for (int i = 0; i < n; ++i) cin >> comp[i + 1];
  for (int i = 1; i <= n; ++i) {
    cin >> k;
    before[i] = k;
    for (int j = 0; j < k; ++j) {
      int idx;
      cin >> idx;
      dpnd[idx].push_back(i);
    }
  }
  int ret = min(solve(1), min(solve(2), solve(3)));
  cout << ret << endl;
  return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>

using namespace std;

int comp[222];
vector<int> dpnd[222];
int before[222];
int n;

int solve(int curr) {
  int bfr[222];
  memcpy(bfr, before, sizeof(before));
  vector<int> finish[4];
  int done = 0;
  for (int i = 1; i <= n; ++i) {
    if (bfr[i] == 0) finish[comp[i]].push_back(i);
  }
  int ret = 0;
  while (done < n) {
    ret += finish[curr].size();
    for (int i = 0; i < finish[curr].size(); ++i) {
      done++;
      int idx = finish[curr][i];
      bfr[idx]--;
      if (bfr[idx] == 0) finish[comp[idx]].push_back(idx);
    }
    if (done == n) break;
    ret++;
    curr++;
    if (curr == 4) curr = 1;
  }
  return ret;
}

int main() {
  cin >> n;
  for (int i = 0; i < n; ++i) {
    int type;
    cin >> type;
    comp[i + 1] = type;
  }
  for (int i = 0; i < n; ++i) {
    int k;
    cin >> k;
    for (int j = 0; j < k; ++j) {
      int dep;
      cin >> dep;
      dpnd[j+1].push_back(dep);
    }
  }
  int ret = min(solve(1), min(solve(2), solve(3)));
  cout << ret << endl;
  return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 100005
#define Long long long
#define For(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
int next[N],son[N],ed[N],cnt;
void link(int x,int y){next[++cnt]=son[x]; son[x]=cnt; ed[cnt]=y;}
int st,en,q[N],n,sum,Ret,Ans;
int vis[N],du[N],be[N],tmp[N];
void work(int now){
    st=0; en=0;
    For(t,1,n) if(!vis[t] && !du[t] && be[t]==now) q[++en]=t;
    while(st<en){
        int u=q[++st]; vis[u]=1;  sum--;
        for(int i=son[u];i;i=next[i]){
            int v=ed[i]; du[v]--;
            if(!du[v] && !vis[v] && be[v]==now) q[++en]=v;
        }
    }
    if(!sum){
        Ans=min(Ans,Ret);
        return;
    }
    Ret++; work(now%3+1);
}
int main(){
    scanf("%d",&n);
    For(i,1,n) scanf("%d",&be[i]);
    For(i,1,n){
        scanf("%d",&du[i]);
        For(j,1,du[i]){
            int y; scanf("%d",&y);
            link(y,i);
        }
    }
    For(i,1,n) tmp[i]=du[i];

    Ans=0x7f7f7f7f;
    For(i,1,n) du[i]=tmp[i],vis[i]=0; sum=n; Ret=0; work(1);
    For(i,1,n) du[i]=tmp[i],vis[i]=0; sum=n; Ret=0; work(2);
    For(i,1,n) du[i]=tmp[i],vis[i]=0; sum=n; Ret=0; work(3);

    printf("%d\n",Ans+n);
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <deque>
#include <queue>
#include <stack>

#define sc scanf
#define pr printf
#define fi first
#define se second
#define pb push_back
#define p_b pop_back
#define pf push_front
#define p_f pop_front
#define mp make_pair
#define lli long long int
#define p_q priority_queue
#define fin freopen( "milk.in", "r", stdin );
#define fout freopen( "input.txt", "w", stdout );
#define dist( x, xx, y, yy ) sqrt( (x - y) * (x - y) + (xx - yy) * (xx - yy) )
using namespace std;
int a, b[211], c[211], d[211][211], co[4][4] = {0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 1, 0, 1 , 2, 0}, ans = 9999999999;
bool used[201];

void dfs( int x, int g )
{
    used[x] = true;
    int mx = -1;
    for( int i = 1; i <= a; i++ ){
        if( !used[i] ){
            bool b1 = true;
            for( int j = 1; j <= b[i]; j++ ){
                if( !used[d[i][j]] )b1 = false;
            }
            if( b1 ){
                dfs( i, g + 1 + co[c[x]][c[i]] );
                mx = 0;
            }
        }
    }
    if( mx == -1 ) ans = min(ans, g);
    used[x] = false;
}

int main()
{
    sc("%d", &a);
    for( int i = 1; i <= a; i++ )sc("%d", &c[i]);
    for( int i = 1; i <= a; i++ ){
        sc("%d", &b[i]);
        for( int j = 1; j <= b[i]; j++ )sc("%d", &d[i][j]);
    }
    for( int i = 1; i <= a; i++ ){
        if( !b[i] )dfs(i, 1);
    }
    pr("%d", ans);
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <deque>
#include <queue>
#include <stack>

#define sc scanf
#define pr printf
#define fi first
#define se second
#define pb push_back
#define p_b pop_back
#define pf push_front
#define p_f pop_front
#define mp make_pair
#define lli long long int
#define p_q priority_queue
#define fin freopen( "milk.in", "r", stdin );
#define fout freopen( "input.txt", "w", stdout );
#define dist( x, xx, y, yy ) sqrt( (x - y) * (x - y) + (xx - yy) * (xx - yy) )
using namespace std;
int a, b[211], c[211], d[211][211], co[4][4] = {0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 1, 0, 1 , 2, 0}, ans = 9999999999;
bool used[201];

void dfs( int x, int g )
{
    used[x] = true;
    int mx = -1;
    for( int i = 1; i <= a; i++ ){
        if( !used[i] ){
            bool b1 = true;
            for( int j = 1; j <= b[i]; j++ ){
                if( !used[d[i][j]] )b1 = false;
            }
            if( b1 ){
                dfs( i, g + 1 + co[c[x]][c[i]] );
                mx = 0;
            }
        }
    }
    if( mx == -1 ) ans = min(ans, g);
    used[x] = false;
}

int main()
{
    sc("%d", &a);
    for( int i = 1; i <= a; i++ )sc("%d", &c[i]);
    for( int i = 1; i <= a; i++ ){
        sc("%d", &b[i]);
        for( int j = 1; j <= b[i]; j++ )sc("%d", &d[i][j]);
    }
    for( int i = 1; i <= a; i++ ){
        if( !b[i] ){
            dfs(i, 1);
            break;
        }
    }
    pr("%d", ans);
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <deque>
#include <queue>
#include <stack>

#define sc scanf
#define pr printf
#define fi first
#define se second
#define pb push_back
#define p_b pop_back
#define pf push_front
#define p_f pop_front
#define mp make_pair
#define lli long long int
#define p_q priority_queue
#define fin freopen( "milk.in", "r", stdin );
#define fout freopen( "input.txt", "w", stdout );
#define dist( x, xx, y, yy ) sqrt( (x - y) * (x - y) + (xx - yy) * (xx - yy) )
using namespace std;
int a, b[211], c[211], d[211][211], ans = 9999999999;
bool used[201];

bool sanj( int x )
{
    for( int i = 1; i <= b[x]; i++ ){
        if( !used[d[x][i]] )return false;
    }
    return true;
}

int main()
{
    sc("%d", &a);
    for( int i = 1; i <= a; i++ )sc("%d", &c[i]);
    for( int i = 1; i <= a; i++ ){
        sc("%d", &b[i]);
        for( int j = 1; j <= b[i]; j++ )sc("%d", &d[i][j]);
    }
    for( int i = 1; i <= 3; i++ ){
        for( int j = 1; j <= a; j++ )used[j] = false;
        int j = 1;
        for( j; ; j++ ){
            bool b1 = true;
            for( int h = 1; h <= a; h++ ){
                if( !used[h] )b1 = false;
            }
            if( b1 )break;
            for( int h1 = 1; h1 <= a; h1++ ){
                for( int h = 1; h <= a; h++ ){
                    if( c[h] == (i + j) % 3 + 1 && sanj(h) && !used[h] )used[h] = true;
                }
            }
        }
        ans = min(ans, j - 1);
    }
    pr("%d", ans + a - 1);
}


# include <stdio.h>
# include <string.h>

int n,end;

int n1[250];

bool vis1[250];

int ans=0;

struct bet
{
	int len;

	bool vis[250];
};
bet f[250],f1[250];

int main()
{
	scanf("%d",&n);

	for (int i=1;i<=n;i++) scanf("%d",&n1[i]);

	for (int i=1;i<=n;i++)
	{
		scanf("%d",&f[i].len);

		for (int j=0;j<f[i].len;j++)
		{int t;
			scanf("%d",&t);

			f[i].vis[t]=1;
		}
	}

	int dur,minn;

	memset(vis1,0,sizeof(vis1));
	for (int i=1;i<=n;i++) f1[i]=f[i];

	dur=1,minn=0,end=n;

	while(end != 0)
	{int q=0;

		for (int j=1;j<=n;j++)
		{
			if(vis1[j] == 0 && f1[j].len == 0 && n1[j] == dur)
			{q=1;
				minn++;
				end--;vis1[j]=1;

				for (int jj=1;jj<=n;jj++) if(f1[jj].vis[j] == 1) f1[jj].vis[j]=0,f1[jj].len--;

				break;
			}
		}

		if(q == 0) minn++,dur++;

		if(dur > 3) dur-=3;
	}

	ans=minn;

	memset(vis1,0,sizeof(vis1));
	for (int i=1;i<=n;i++) f1[i]=f[i];

	dur=2,minn=0,end=n;

	while(end != 0)
	{int q=0;

		for (int j=1;j<=n;j++)
		{
			if(vis1[j] == 0 && f1[j].len == 0 && n1[j] == dur)
			{q=1;
				minn++;
				end--;vis1[j]=1;

				for (int jj=1;jj<=n;jj++) if(f1[jj].vis[j] == 1) f1[jj].vis[j]=0,f1[jj].len--;

				break;
			}
		}

		if(q == 0) minn++,dur++;

		if(dur > 3) dur-=3;
	}

	if(minn < ans) ans=minn;

	memset(vis1,0,sizeof(vis1));
	for (int i=1;i<=n;i++) f1[i]=f[i];

	dur=3,minn=0,end=n;

	while(end != 0)
	{int q=0;

		for (int j=1;j<=n;j++)
		{
			if(vis1[j] == 0 && f1[j].len == 0 && n1[j] == dur)
			{q=1;
				minn++;
				end--;vis1[j]=1;

				for (int jj=1;jj<=n;jj++) if(f1[jj].vis[j] == 1) f1[jj].vis[j]=0,f1[jj].len--;

				break;
			}
		}

		if(q == 0) minn++,dur++;

		if(dur > 3) dur-=3;
	}

	if(minn < ans) ans=minn;

	printf("%d",ans);

	getchar();getchar();
}


# include <stdio.h>

int n,end;

int n1[250];

bool vis1[250];

int ans=0;

struct bet
{
	int len;

	bool vis[250];
};
bet f[250];

int main()
{
	scanf("%d",&n);
	end=n;
	for (int i=1;i<=n;i++) scanf("%d",&n1[i]);

	for (int i=1;i<=n;i++)
	{
		scanf("%d",&f[i].len);

		for (int j=0;j<f[i].len;j++)
		{int t;
			scanf("%d",&t);

			f[i].vis[t]=1;
		}
	}

	int dur=0;

	for (int j=1;j<=n;j++)
	if(f[j].len == 0) {dur=n1[j];break;}

	while(end != 0)
	{int q=0;

		for (int j=1;j<=n;j++)
		{
			if(vis1[j] == 0 && f[j].len == 0 && n1[j] == dur)
			{q=1;
				ans++;
				end--;vis1[j]=1;

				for (int jj=1;jj<=n;jj++) if(f[jj].vis[j] == 1) f[jj].vis[j]=0,f[jj].len--;

				break;
			}
		}

		if(q == 0) ans++,dur++;

		if(dur > 3) dur-=3;
	}

	printf("%d",ans);

	getchar();getchar();
}


#include <bits/stdc++.h>
#define MOD 1000000007
#define Nmax 1005
#define INF 20000
#define eps 0.000000000001

using namespace std;

int comp[Nmax],cost[Nmax][5][5],grad[Nmax],v[Nmax],len,nrnoduri,depl[5][5],fr[Nmax];
long long dp[Nmax][5][5];
int n;
long long sol=INF;
vector <int> L[Nmax],T[Nmax];

struct el
{
    int nod,cam1,cam2;
    long long cost;
    bool operator <(const el &A) const
    {
        return cost>A.cost;
    }
};
priority_queue <el> Q;

inline int COST()
{
    int sol=len,i,j,nr[5],v1,v2,v3,val,f,l;
    for(i=1;i<=3;++i) nr[i]=0;
    for(i=1;i<=len;++i) ++nr[comp[v[i]]];
    for(i=1;i<=3;++i)
        for(j=1;j<=3;++j) cost[nrnoduri][i][j]=INF;
    for(v1=1;v1<=3;++v1)
        for(v2=1;v2<=3;++v2)
            for(v3=1;v3<=3;++v3)
            {
                val=nrnoduri; f=l=0;
                if(nr[v1] && nr[v2])
                {
                    val+=depl[v1][v2];
                    if(nr[v2] && nr[v3]) val+=depl[v2][v3];
                }
                else
                    if(nr[v1] && nr[v3]) val+=depl[v1][v3];
                    else
                        if(nr[v2] && nr[v3]) val+=depl[v2][v3];

                if(nr[v1]) f=v1;
                else
                    if(nr[v2]) f=v2;
                    else
                        if(nr[v3]) f=v3;
                if(nr[v3]) l=v3;
                else
                    if(nr[v2]) l=v2;
                    else
                        if(nr[v1]) l=v1;
                cost[nrnoduri][f][l]=val;
            }
}

inline void Dijkstra()
{
    el w,w1;
    int i,j;
    for(i=1;i<=3;++i)
        for(j=1;j<=3;++j)
        {
            w.nod=1; w.cam1=i; w.cam2=j; w.cost=cost[1][i][j]; Q.push(w);
        }
    while(!Q.empty())
    {
        w=Q.top(); Q.pop();
        //cout<<w.nod<<" "<<w.cost<<"\n";
        if(w.nod==nrnoduri)
        {
            sol=min(sol,w.cost);
            continue;
        }
        for(i=1;i<=3;++i)
            for(j=1;j<=3;++j)
            {
                w1.nod= w.nod+1; w1.cam1=i; w1.cam2=j; w1.cost=w.cost+depl[w.cam2][i]+cost[w1.nod][i][j];
                if(dp[w1.nod][w1.cam1][w1.cam2]>w1.cost)
                {
                    dp[w1.nod][w1.cam1][w1.cam2]=w1.cost;
                    Q.push(w1);
                }
            }
    }
}

int main()
{
    int i,j,k,x,nr,cnt;
    vector <int> ::iterator it;
    #ifndef ONLINE_JUDGE
        freopen ("date.in","r",stdin);
        freopen ("date.out","w",stdout);
    #endif
    cin.sync_with_stdio(0);
    cin>>n;
    depl[1][2]=1; depl[1][3]=2; depl[2][1]=2; depl[2][3]=1; depl[3][1]=1; depl[3][2]=2;
    for(i=1;i<=n;++i) cin>>comp[i];
    for(i=1;i<=n;++i)
    {
        cin>>nr;
        grad[i]=nr;
        while(nr--)
        {
            cin>>x;
            L[i].push_back(x);
            T[x].push_back(i);
        }
    }
    nrnoduri=cnt=0;
    while(cnt<n)
    {
        len=0; ++nrnoduri;
        for(i=1;i<=n;++i)
            if(!grad[i] && !fr[i])
            {
                v[++len]=i; ++cnt; fr[i]=true;
            }
        //for(i=1;i<=len;++i) cout<<v[i]<<" ";
        //cout<<"\n";
        for(i=1;i<=len;++i)
            for(it=T[v[i]].begin();it!=T[v[i]].end();++it) --grad[*it];
        COST();
    }
    //cout<<cost[2][1][2]<<"\n";
    for(i=1;i<=nrnoduri;++i)
        for(j=1;j<=3;++j)
            for(k=1;k<=3;++k) dp[i][j][k]=INF;
    Dijkstra();
    cout<<sol;
    return 0;
}


#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int N, A[202];
vector<int> V[202];
int grad[202], fgrad[202];
bool S[202];
int result = 0x3f3f3f3f;

int main()
{
	cin >> N;
	for (int i = 1; i <= N; ++i)
		cin >> A[i];
	for (int i = 1, size; i <= N; ++i)
	{
		cin >> size;
		for (int j = 1, before; j <= size; ++j)
		{
			cin >> before;
			V[before].push_back(i);
			++fgrad[i];
		}
	}

	for (int begin = 1; begin <= 3; ++begin)
	{
		memset(S, 0, sizeof(S));
		memcpy(grad, fgrad, sizeof(grad));

		int resnow = 0;
		int total = N, color = begin;
		while (total)
		{
			int now = -1;
			for (int i = 1; i <= N; ++i)
				if (!S[i] && A[i] == color && grad[i] == 0)
				{
					now = i;
					break;
				}

			if (now == -1)
			{
				++color, ++resnow;
				if (color == 4) color = 1;
				continue;
			}

			S[now] = true;
			--total;
			for (vector<int>::iterator it = V[now].begin(); it != V[now].end(); ++it)
				--grad[*it];
		}

		result = min(result, resnow);
	}

	cout << result + N << '\n';
}


/*
Author : OmarEl-Mohandes
PROG   : C
LANG   : C++
*/
#include <map>
#include <string>
#include <deque>
#include <queue>
#include <stack>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
#include <set>
#include <complex>
#include <memory.h>
using namespace std;
#define pb push_back
#define all(v) v.begin(),v.end()
#define sz size()
#define rep(i,m) for(int i=0;i<(int)m;i++)
#define REP(i,k,m) for(int i=k;i<(int)m;i++)
#define mem(a,b) memset(a,b,sizeof(a))
#define mp make_pair
typedef stringstream ss;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<string> vs;
typedef vector<int> vi;
typedef vector<vector<int> > vii;
typedef long long ll;
#define oo ((int)1e9)
int n;
int com[201];
vector<int> dep[201];
bool finished[201];
int dfs(int c)
{
    int cnt = 0;
    rep(i , n)
        if(!finished[i] && com[i] == c)
        {
            bool f = 1;
            rep(j , dep[i].size())
                if(!finished[dep[i][j]])
                    f = 0;
            if(f)
                finished[i] = 1 , cnt ++;
        }
    rep(i , n){
        if(!finished[i] && com[i] == c){
            bool f = 1;
            rep(j , dep[i].size())
                if(!finished[dep[i][j]])
                {
                    f = 0;
                    break;
                }
            if(f)
                finished[i] = 1 , cnt ++;
        }
    }
    if(count(finished , finished+n , 1) == n)
        return cnt;
    return cnt + 1 + dfs((c + 1)%3);
}
int main()
{
    //freopen("test.in" , "rt" , stdin);
    //freopen("C.out" , "wt" , stdout);
    scanf("%d" , &n);
    int t;
    rep(i , n){
        scanf("%d" , &t);
        com[i] = t-1;
    }
    int a;
    rep(i , n){
        scanf("%d" , &t);
        rep(j , t)
            scanf("%d" , &a) , a-- , dep[i].pb(a);
    }
    int mn = 1e9;
    rep(i , 3)
    {
        memset(finished , 0 , sizeof finished);
        int r = dfs(i);
        mn = min(r , mn);
    }
    cout << mn << endl;
    return 0;

}


/*
Author : OmarEl-Mohandes
PROG   : C
LANG   : C++
*/
#include <map>
#include <string>
#include <deque>
#include <queue>
#include <stack>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
#include <set>
#include <complex>
#include <memory.h>
using namespace std;
#define pb push_back
#define all(v) v.begin(),v.end()
#define sz size()
#define rep(i,m) for(int i=0;i<(int)m;i++)
#define REP(i,k,m) for(int i=k;i<(int)m;i++)
#define mem(a,b) memset(a,b,sizeof(a))
#define mp make_pair
typedef stringstream ss;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<string> vs;
typedef vector<int> vi;
typedef vector<vector<int> > vii;
typedef long long ll;
#define oo ((int)1e9)
int n;
int com[201];
vector<int> dep[201];
bool finished[201];
int dfs(int c)
{
    int cnt = 0;
    bool ff = 1;
    while(ff)
    {
        ff = 0;
        rep(i , n){
            if(!finished[i] && com[i] == c){
                bool f = 1;
                rep(j , dep[i].size())
                    if(!finished[dep[i][j]])
                    {
                        f = 0;
                        break;
                    }
                if(f)
                    finished[i] = 1 , cnt ++ , ff = 1;
            }
        }
    }
    if(count(finished , finished+n , 1) == n)
        return cnt;
    return cnt + 1 + dfs((c + 1)%3);
}
int main()
{
//  freopen("test.in" , "rt" , stdin);
    //freopen("C.out" , "wt" , stdout);
    scanf("%d" , &n);
    int t;
    rep(i , n){
        scanf("%d" , &t);
        com[i] = t-1;
    }
    int a;
    rep(i , n){
        scanf("%d" , &t);
        rep(j , t)
            scanf("%d" , &a) , a-- , dep[i].pb(a);
    }
    int mn = 1e9;
    rep(i , 3)
    {
        memset(finished , 0 , sizeof finished);
        int r = dfs(i);
        mn = min(r , mn);
    }
    cout << mn << endl;
    return 0;

}


#include <fstream>
#include <iostream>
#include <vector>
#include <memory.h>
using namespace std;

#ifndef ONLINE_JUDGE
    ifstream inf("Input.txt");
    ofstream outf("Output.txt");
#else
    #define inf cin
    #define outf cout
#endif

int n;
vector<int> a[3];
vector<int> adj[210];
int c[210];

bool was[210];
void dfs(int v, int anc = -1) {
    was[v] = true;
    //bool flag = false;
    for (int i = 0; i < (int)adj[v].size(); i++)
        if (adj[v][i] != anc && !was[adj[v][i]]) dfs(adj[v][i], anc);
    a[c[v]-1].push_back(v);
}

int main() {
    inf >> n;
    for (int i = 0; i < n; i++)
        inf >> c[i];
    for (int i = 0; i < n; i++) {
        int k; inf >> k;
        adj[i].resize(k);
        for (int j = 0; j < k; j++) {
            inf >> adj[i][j];
            --adj[i][j];
            //int t; inf >> t;
            //adj[t-1].push_back(i);
        }
    }

    for (int i = 0; i < n; i++)
        if (!was[i]) dfs(i);

    int min_tm = 2000000000;
    for (int st = 0; st < 3; ++st) {
        int cnt = n, tm = 0;
        memset(was, 0, sizeof(was));
        int pos[3] = {0,0,0};
        int curr = st;
        while (cnt > 0) {
            while (pos[curr] < (int)a[curr].size()) {
                bool flag = true;
                int v = a[curr][pos[curr]];
                for (int i = 0; i < (int)adj[v].size(); i++)
                    if (!was[adj[v][i]]) {
                        flag = false;
                        break;
                    }
                if (flag) was[v] = true, ++pos[curr], --cnt;
                else break;
            }
            curr = (curr+1) % 3;
            ++tm;
        }
        min_tm = min(min_tm, tm-1);
    }

    outf << min_tm+n << endl;
}


#include <fstream>
#include <iostream>
#include <vector>
#include <memory.h>
using namespace std;

#ifndef ONLINE_JUDGE
    ifstream inf("Input.txt");
    ofstream outf("Output.txt");
#else
    #define inf cin
    #define outf cout
#endif

int n;
vector<int> a[3];
vector<int> adj[210];
int c[210];

bool was[210];
void dfs(int v/*, int anc = -1*/) {
    was[v] = true;
    for (int i = 0; i < (int)adj[v].size(); i++)
        if (/*adj[v][i] != anc && */!was[adj[v][i]]) dfs(adj[v][i]/*, v*/);
    a[c[v]-1].push_back(v);
}

int main() {
    inf >> n;
    for (int i = 0; i < n; i++)
        inf >> c[i];
    for (int i = 0; i < n; i++) {
        int k; inf >> k;
        adj[i].resize(k);
        for (int j = 0; j < k; j++) {
            inf >> adj[i][j];
            --adj[i][j];
        }
    }

    for (int i = 0; i < n; i++)
        if (!was[i]) dfs(i);

    int min_tm = 2000000000;
    for (int st = 0; st < 3; ++st) {
        int cnt = n, tm = 0;
        memset(was, 0, sizeof(was));
        int pos[3] = {0,0,0};
        int curr = st;
        while (cnt > 0) {
            pos[curr] = 0;
            while (pos[curr] < (int)a[curr].size()) if (!was[pos[curr]]) {
                bool flag = true;
                int v = a[curr][pos[curr]];
                for (int i = 0; i < (int)adj[v].size(); i++)
                    if (!was[adj[v][i]]) {
                        flag = false;
                        break;
                    }
                if (flag) was[v] = true, --cnt;
                ++pos[curr];
                //else break;
            }
            curr = (curr+1) % 3;
            ++tm;
        }
        min_tm = min(min_tm, tm-1);
    }

    outf << min_tm+n << endl;
}


#include <fstream>
#include <iostream>
#include <vector>
#include <memory.h>
using namespace std;

#ifndef ONLINE_JUDGE
    ifstream inf("Input.txt");
    ofstream outf("Output.txt");
#else
    #define inf cin
    #define outf cout
#endif

int n;
vector<int> a[3];
vector<int> adj[210];
int c[210];
int cc[210];
int adj2[210][210];

bool was[210];
void dfs(int v/*, int anc = -1*/) {
    was[v] = true;
    for (int i = 0; i < (int)adj[v].size(); i++)
        if (/*adj[v][i] != anc && */!was[adj[v][i]]) dfs(adj[v][i]/*, v*/);
    a[c[v]-1].push_back(v);
}

int main() {
    inf >> n;
    for (int i = 0; i < n; i++)
        inf >> c[i];
    for (int i = 0; i < n; i++) {
        int k; inf >> k;
        adj[i].resize(k);
        for (int j = 0; j < k; j++) {
            inf >> adj[i][j];
            --adj[i][j];
            adj2[i][adj[i][j]] = 1;
        }
    }

    for (int i = 0; i < n; i++)
        if (!was[i]) dfs(i);

    int min_tm = 2000000000;
    for (int st = 0; st < 3; ++st) {
        int cnt = n, tm = 0;
        memset(was, 0, sizeof(was));
        int pos[3] = {0,0,0};
        int curr = st;
        memset(cc, 0, sizeof(cc));
        while (cnt > 0) {
            pos[curr] = 0;
            while (pos[curr] < (int)a[curr].size()) {
                //bool flag = true;
                int v = a[curr][pos[curr]];
                /*for (int i = 0; i < (int)adj[v].size(); i++)
                    if (!was[adj[v][i]]) {
                        flag = false;
                        break;
                    }*/
                if (!was[v] && cc[v] == (int)adj[v].size()) {
                    was[v] = true;
                    --cnt;
                    for (int i = 0; i < n; i++)
                        if (adj2[i][v]) ++cc[i];
                }
                ++pos[curr];
                //else break;
            }
            curr = (curr+1) % 3;
            ++tm;
        }
        min_tm = min(min_tm, tm-1);
    }

    outf << min_tm+n << endl;
}


#include <fstream>
#include <iostream>
#include <vector>
#include <memory.h>
using namespace std;

#ifndef ONLINE_JUDGE
    ifstream inf("Input.txt");
    ofstream outf("Output.txt");
#else
    #define inf cin
    #define outf cout
#endif

int n;
vector<int> a[3];
vector<int> adj[210];
int c[210];

bool was[210];
void dfs(int v/*, int anc = -1*/) {
    was[v] = true;
    for (int i = 0; i < (int)adj[v].size(); i++)
        if (/*adj[v][i] != anc && */!was[adj[v][i]]) dfs(adj[v][i]/*, v*/);
    a[c[v]-1].push_back(v);
}

int main() {
    inf >> n;
    for (int i = 0; i < n; i++)
        inf >> c[i];
    for (int i = 0; i < n; i++) {
        int k; inf >> k;
        adj[i].resize(k);
        for (int j = 0; j < k; j++) {
            inf >> adj[i][j];
            --adj[i][j];
        }
    }

    for (int i = 0; i < n; i++)
        if (!was[i]) dfs(i);

    int min_tm = 2000000000;
    for (int st = 0; st < 3; ++st) {
        int cnt = n, tm = 0;
        memset(was, 0, sizeof(was));
        int pos[3] = {0,0,0};
        int curr = st;
        while (cnt > 0) {
            pos[curr] = 0;
            while (pos[curr] < (int)a[curr].size()) {
                bool flag = true;
                int v = a[curr][pos[curr]];
                for (int i = 0; i < (int)adj[v].size(); i++)
                    if (!was[adj[v][i]]) {
                        flag = false;
                        break;
                    }
                if (flag) was[v] = true, --cnt;
                ++pos[curr];
                //else break;
            }
            curr = (curr+1) % 3;
            ++tm;
        }
        min_tm = min(min_tm, tm-1);
    }

    outf << min_tm+n << endl;
}


#include <fstream>
#include <iostream>
#include <vector>
#include <memory.h>
using namespace std;

#ifndef ONLINE_JUDGE
    ifstream inf("Input.txt");
    ofstream outf("Output.txt");
#else
    #define inf cin
    #define outf cout
#endif

int n;
vector<int> a[3];
vector<int> adj[210];
int c[210];

bool was[210];
void dfs(int v, int anc = -1) {
    was[v] = true;
    for (int i = 0; i < (int)adj[v].size(); i++)
        if (adj[v][i] != anc && !was[adj[v][i]]) dfs(adj[v][i], v);
    a[c[v]-1].push_back(v);
}

int main() {
    inf >> n;
    for (int i = 0; i < n; i++)
        inf >> c[i];
    for (int i = 0; i < n; i++) {
        int k; inf >> k;
        adj[i].resize(k);
        for (int j = 0; j < k; j++) {
            inf >> adj[i][j];
            --adj[i][j];
        }
    }

    for (int i = 0; i < n; i++)
        if (!was[i]) dfs(i);

    int min_tm = 2000000000;
    for (int st = 0; st < 3; ++st) {
        int cnt = n, tm = 0;
        memset(was, 0, sizeof(was));
        int pos[3] = {0,0,0};
        int curr = st;
        while (cnt > 0) {
            while (pos[curr] < (int)a[curr].size()) {
                bool flag = true;
                int v = a[curr][pos[curr]];
                for (int i = 0; i < (int)adj[v].size(); i++)
                    if (!was[adj[v][i]]) {
                        flag = false;
                        break;
                    }
                if (flag) was[v] = true, ++pos[curr], --cnt;
                else break;
            }
            curr = (curr+1) % 3;
            ++tm;
        }
        min_tm = min(min_tm, tm-1);
    }

    outf << min_tm+n << endl;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <climits>
#include <string>

using namespace std;

#define mp make_pair
#define F first
#define S second
#define N 200

int n;
int vet[N];
set<int> dep[N], aux[N];
int mat[3][3] = { 0, 1, 2,
		  2, 0, 1,
		  1, 2, 0};

int solve(int start, set<int>* dep)
{
	int s = start, r = 0, c = 1, g;
	int vis[N] = {0};
	while (c)
	{
		c = 0;
		g = 0;
		for (int i = 0; i < n; ++i)
		{
			c |= dep[i].size();
			if (dep[i].empty() && vet[i] == s && !vis[i])
			{
				g = 1;
				r++;
				vis[i] = 1;
				for (int j = 0; j < n; ++j)
					dep[j].erase(i);
			}
		}
		if (!g) r++, s = (s+1)%3;
	}
	return r;
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; ++i)
		scanf("%d", &vet[i]), --vet[i];
	for (int i = 0; i < n; ++i)
	{
		int a, b; scanf("%d", &a);
		for (int j = 0; j < a; ++j)
		{
			scanf("%d", &b);
			dep[i].insert(b-1);
		}
	}

	int res = INT_MAX;
	for (int i = 0; i < n; ++i) aux[i] = dep[i];
	res = min(res, solve(0, aux));
	for (int i = 0; i < n; ++i) aux[i] = dep[i];
	res = min(res, solve(1, aux));
	for (int i = 0; i < n; ++i) aux[i] = dep[i];
	res = min(res, solve(2, aux));
	printf("%d\n", res);

	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <climits>
#include <string>

using namespace std;

#define mp make_pair
#define F first
#define S second
#define N 200

int n;
int vet[N];
set<int> dep[N], aux[N];
int mat[3][3] = { 0, 1, 2,
		  2, 0, 1,
		  1, 2, 0};

int solve(int start, set<int>* dep)
{
	int s = start, r = 0, c = 1, g, z = 4;
	int vis[N] = {0};
	while (c)
	{
		c = 0;
		g = 0;
		for (int i = 0; i < n; ++i)
		{
			c |= !vis[i];
			if (dep[i].empty() && vet[i] == s && !vis[i])
			{
				g = 1;
				r++;
				vis[i] = 1;
				for (int j = 0; j < n; ++j)
					dep[j].erase(i);
			}
		}
		if (!g) r++, s = (s+1)%3;
	}
	return r-1;
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; ++i)
		scanf("%d", &vet[i]), --vet[i];
	for (int i = 0; i < n; ++i)
	{
		int a, b; scanf("%d", &a);
		for (int j = 0; j < a; ++j)
		{
			scanf("%d", &b);
			dep[i].insert(b-1);
		}
	}

	int res = INT_MAX;
	for (int i = 0; i < n; ++i) aux[i] = dep[i];
	res = min(res, solve(0, aux));
	for (int i = 0; i < n; ++i) aux[i] = dep[i];
	res = min(res, solve(1, aux));
	for (int i = 0; i < n; ++i) aux[i] = dep[i];
	res = min(res, solve(2, aux));
	printf("%d\n", res);

	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <climits>
#include <string>

using namespace std;

#define mp make_pair
#define F first
#define S second
#define N 200

int n;
int vet[N];
set<int> dep[N], aux[N];
int mat[3][3] = { 0, 1, 2,
		  2, 0, 1,
		  1, 2, 0};

int solve(int start, set<int>* dep)
{
	int s = start, r = 0, c = 1, g, z = 4;
	int vis[N] = {0};
	while (z)
	{
		c = 0;
		g = 0;
		for (int i = 0; i < n; ++i)
		{
			c |= dep[i].size();
			if (dep[i].empty() && vet[i] == s && !vis[i])
			{
				g = 1;
				r++;
				vis[i] = 1;
				for (int j = 0; j < n; ++j)
					dep[j].erase(i);
			}
		}
		if (!g) r++, s = (s+1)%3;
		if (!c) --z;
		else z = 4;
	}
	return r;
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; ++i)
		scanf("%d", &vet[i]), --vet[i];
	for (int i = 0; i < n; ++i)
	{
		int a, b; scanf("%d", &a);
		for (int j = 0; j < a; ++j)
		{
			scanf("%d", &b);
			dep[i].insert(b-1);
		}
	}

	int res = INT_MAX;
	for (int i = 0; i < n; ++i) aux[i] = dep[i];
	res = min(res, solve(0, aux));
	for (int i = 0; i < n; ++i) aux[i] = dep[i];
	res = min(res, solve(1, aux));
	for (int i = 0; i < n; ++i) aux[i] = dep[i];
	res = min(res, solve(2, aux));
	printf("%d\n", res);

	return 0;
}


#include <iostream>
#include <cstdio>
#include <fstream>

#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <utility>
#include <string>
#include <cstring>

#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cassert>
#include <memory.h>
using namespace std;

#define fr(i, n) for (int i = 0; i < (int)(n); i++)
#define fb(i, n) for (int i = n - 1; i >= 0; i--)
#define all(a) (a).begin(), (a).end()
#define _(a, b) memset(a, b, sizeof(a))
#define mp make_pair
#define pb push_back
#define sz(v) ((int)(v).size())

typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;

inline int ni() { int a; scanf("%d", &a); return a; }
inline double nf() { double a; scanf("%lf", &a); return a; }
template <class T> void out(T a, T b) { bool first = true; for (T i = a; i != b; i++) { if (!first) printf(" "); first = false; cout << *i; } puts(""); }
template <class T> void outl(T a, T b) { for (T i = a; i != b; i++) cout << *i << "\n"; }

const int MAXN = 300;

int n;
int c[MAXN];
vi v[MAXN];
int k;

int bestans = 2e9, ans;

bool u[MAXN];
int val, cur;

inline bool good(int num) {
	fr(i, sz(v[num])) {
		if (!u[v[num][i]])
			return false;
	}
	return true;
}

int main() {
	n = ni();
	fr(i, n) {
		c[i] = ni();
		c[i]--;
	}
	fr(i, n) {
		k = ni();
		v[i].resize(k);
		fr(j, k) {
			v[i][j] = ni();
			v[i][j]--;
		}
	}
	for (int start = 0; start <= 2; start++) {
		ans = -1;
		_(u, 0);
		val = 0;
		cur = start;
		do {
			ans++;
			fr(i, n) {
				if (!u[i] && good(i)) {
					val++;
					ans++;
					u[i] = true;
				}
			}
			cur = (cur + 1) % 3;
		} while (val < n);
		bestans = min(bestans, ans);
	}
	cout << ans << endl;
}


#include <iostream>
#include <cstdio>
#include <fstream>

#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <utility>
#include <string>
#include <cstring>

#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cassert>
#include <memory.h>
using namespace std;

#define fr(i, n) for (int i = 0; i < (int)(n); i++)
#define fb(i, n) for (int i = n - 1; i >= 0; i--)
#define all(a) (a).begin(), (a).end()
#define _(a, b) memset(a, b, sizeof(a))
#define mp make_pair
#define pb push_back
#define sz(v) ((int)(v).size())

typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;

inline int ni() { int a; scanf("%d", &a); return a; }
inline double nf() { double a; scanf("%lf", &a); return a; }
template <class T> void out(T a, T b) { bool first = true; for (T i = a; i != b; i++) { if (!first) printf(" "); first = false; cout << *i; } puts(""); }
template <class T> void outl(T a, T b) { for (T i = a; i != b; i++) cout << *i << "\n"; }

const int MAXN = 300;

int n;
int c[MAXN];
vi v[MAXN];
int k;

int bestans = 2e9, ans;

bool u[MAXN];
int val, cur;

inline bool good(int num) {
	fr(i, sz(v[num])) {
		if (!u[v[num][i]])
			return false;
	}
	return true;
}

int main() {
	n = ni();
	fr(i, n) {
		c[i] = ni();
		c[i]--;
	}
	fr(i, n) {
		k = ni();
		v[i].resize(k);
		fr(j, k) {
			v[i][j] = ni();
			v[i][j]--;
		}
	}
	for (int start = 0; start <= 2; start++) {
		ans = -1;
		_(u, 0);
		val = 0;
		cur = start;
		do {
			ans++;
			bool flag = false;
			do {
				flag = false;
				fr(i, n) {
					if (c[i] == cur && !u[i] && good(i)) {
						val++;
						ans++;
						u[i] = true;
						flag = true;
					}
				}
			} while (flag);
			cur = (cur + 1) % 3;
		} while (val < n);
		bestans = min(bestans, ans);
	}
	cout << bestans << endl;
}


#include <iostream>
#include <cstdio>
#include <fstream>

#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <utility>
#include <string>
#include <cstring>

#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cassert>
#include <memory.h>
using namespace std;

#define fr(i, n) for (int i = 0; i < (int)(n); i++)
#define fb(i, n) for (int i = n - 1; i >= 0; i--)
#define all(a) (a).begin(), (a).end()
#define _(a, b) memset(a, b, sizeof(a))
#define mp make_pair
#define pb push_back
#define sz(v) ((int)(v).size())

typedef long long ll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;

inline int ni() { int a; scanf("%d", &a); return a; }
inline double nf() { double a; scanf("%lf", &a); return a; }
template <class T> void out(T a, T b) { bool first = true; for (T i = a; i != b; i++) { if (!first) printf(" "); first = false; cout << *i; } puts(""); }
template <class T> void outl(T a, T b) { for (T i = a; i != b; i++) cout << *i << "\n"; }

const int MAXN = 300;

int n;
int c[MAXN];
vi v[MAXN];
int k;

int bestans = 2e9, ans;

bool u[MAXN];
int val, cur;

inline bool good(int num) {
	fr(i, sz(v[num])) {
		if (!u[v[num][i]])
			return false;
	}
	return true;
}

int main() {
	n = ni();
	fr(i, n) {
		c[i] = ni();
		c[i]--;
	}
	fr(i, n) {
		k = ni();
		v[i].resize(k);
		fr(j, k) {
			v[i][j] = ni();
			v[i][j]--;
		}
	}
	for (int start = 0; start <= 2; start++) {
		ans = -1;
		_(u, 0);
		val = 0;
		cur = start;
		do {
			ans++;
			bool flag = false;
			do {
				flag = false;
				fr(i, n) {
					if (c[i] == cur && !u[i] && good(i)) {
						val++;
						ans++;
						u[i] = true;
						flag = true;
					}
				}
			} while (flag);
			cur = (cur + 1) % 3;
		} while (val < n);
		bestans = min(bestans, ans);
	}
	cout << ans << endl;
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <string>
#include <cmath>
#include <stack>
#include <list>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
#include <numeric>
#include <utility>
#include <functional>
#include <limits>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int ui;

const double pi = acos(-1.0);

#define oned(a, x1, x2) { cout << #a << ":"; for(int _i = (x1); _i < (x2); _i++){ cout << " " << a[_i]; } cout << endl; }
#define twod(a, x1, x2, y1, y2) { cout << #a << ":" << endl; for(int _i = (x1); _i < (x2); _i++){ for(int _j = (y1); _j < (y2); _j++){ cout << (_j > y1 ? " " : "") << a[_i][_j]; } cout << endl; } }
#define mp(x, y) make_pair(x, y)

int n;
vector<int> comp, needed;
vector<vector<int> > g;

void solve() {
    bool start[3] = {false};
    for(int i = 0; i < n; i++) {
        if(needed[i] == 0) {
            start[comp[i]] = true;
        }
    }

    int s;
    if(start[0] && start[1] && start[2]) s = 0;
    else if(!start[0] && start[1]) s = 1;
    else if(!start[1] && start[2]) s = 2;
    else s = 0;

    int ans = 0, num = 0;
    vector<bool> played(n,false);
    while(num < n) {
        bool changed = false;
        for(int i = 0; i < n; i++) {
            if(!played[i] && !needed[i] && comp[i] == s) {
                num++;
                ans++;
                played[i] = true;
                changed = true;
                for(size_t j = 0; j < g[i].size(); j++) {
                    needed[g[i][j]]--;
                }
            }
        }

        if(!changed) {
            s = (s+1) % 3;
            ans++;
        }
    }

    cout << ans << endl;
}

int main() {
//  freopen("input.in", "r", stdin);
    while(cin >> n) {
        comp = vector<int>(n);
        for(int i = 0; i < n; i++) {
            cin >> comp[i];
            comp[i]--;
        }
        g = vector<vector<int> >(n);
        needed = vector<int>(n);
        for(int i = 0; i < n; i++) {
            int k; cin >> k;
            needed[i] = k;
            for(int j = 0; j < k; j++) {
                int p; cin >> p;
                g[p-1].push_back(i);
            }
        }
        solve();
    }
}


#include <iostream>
#include <fstream>
#include <cstdio>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <string>
#include <cmath>
#include <stack>
#include <list>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
#include <numeric>
#include <utility>
#include <functional>
#include <limits>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int ui;

const double pi = acos(-1.0);

#define oned(a, x1, x2) { cout << #a << ":"; for(int _i = (x1); _i < (x2); _i++){ cout << " " << a[_i]; } cout << endl; }
#define twod(a, x1, x2, y1, y2) { cout << #a << ":" << endl; for(int _i = (x1); _i < (x2); _i++){ for(int _j = (y1); _j < (y2); _j++){ cout << (_j > y1 ? " " : "") << a[_i][_j]; } cout << endl; } }
#define mp(x, y) make_pair(x, y)

int n;
vector<int> comp, tneeded;
vector<vector<int> > g;

void solve() {
    bool start[3] = {false};
    for(int i = 0; i < n; i++) {
        if(tneeded[i] == 0) {
            start[comp[i]] = true;
        }
    }

    int minAns = 1000000;
    for(int S = 0; S < 3; S++) {
        if(!start[S]) continue;
        int s = S;

        vector<int> needed = tneeded;

        int ans = 0, num = 0;
        vector<bool> played(n,false);
        while(num < n) {
            bool changed = false;
            for(int i = 0; i < n; i++) {
                if(!played[i] && !needed[i] && comp[i] == s) {
                    num++;
                    ans++;
                    played[i] = true;
                    changed = true;
                    for(size_t j = 0; j < g[i].size(); j++) {
                        needed[g[i][j]]--;
                    }
                }
            }

            if(!changed) {
                s = (s+1) % 3;
                ans++;
            }
        }

        minAns = min(ans, minAns);
    }

    cout << minAns << endl;
}

int main() {
//	freopen("input.in", "r", stdin);
	while(cin >> n) {
	    comp = vector<int>(n);
	    for(int i = 0; i < n; i++) {
            cin >> comp[i];
            comp[i]--;
	    }
	    g = vector<vector<int> >(n);
	    tneeded = vector<int>(n);
	    for(int i = 0; i < n; i++) {
            int k; cin >> k;
            tneeded[i] = k;
            for(int j = 0; j < k; j++) {
                int p; cin >> p;
                g[p-1].push_back(i);
            }
	    }
		solve();
	}
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 0x73737373
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
void dfs(int now_pos, int ind, int cost, int comp)
{
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    for(int i = 1; i <= n; i++)
    {
        if(i == ind)continue;
        if(check(i))
        {
            int next_cost = cost + dcost[now_pos][p[i].need] + 1;
            vis[i] = true;
            dfs(p[i].need, i, next_cost, comp + 1);
            vis[i] = false;
        }
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].need;
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].pnum;
        for(int j = 0; j < p[i].pnum; j++)
            cin >> p[i].ps[j];
    }
    for(int i = 1; i <= n; i++)
    {
        if(p[i].pnum == 0)
        {
            memset(vis, false, sizeof(vis));
            vis[i] = true;
            dfs(p[i].need, i, 1, 1);
        }
    }
    printf("%d\n", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
using namespace std;
#define INF 0x73737373
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
set <string> has[1000][3];
set <string> ppp;
map <string, int> min_cost;
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
string get_state()
{
    string ret;
    for(int i = 1; i <= n; i++)
        if(vis[i])ret += i;
    return ret;
}
void dfs(int now_pos, int cost, int comp)
{
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    if(cost >= ret) return;
    string state = get_state();
    if(has[cost][now_pos].count(state)) return;
    has[cost][now_pos].insert(state);
    bool cop[205];
    memset(cop, false, sizeof(cop));
    bool cmp = false;
    for(int i = 1; i <= n; i++)
        if(!vis[i] && p[i].need == now_pos && check(i))
        {
            cost ++;
            comp ++;
            vis[i] = true;
            cop[i] = true;
            cmp = true;
        }
    if(!cmp)return;
    if(ppp.count(state))
    {
        if(cost < min_cost[state])
            min_cost[state] = cost;
        else return;
    }
    else
    {
        min_cost[state] = cost;
        ppp.insert(state);
    }
    for(int i = 0; i < 3; i++)
    {
        dfs(i, cost + dcost[now_pos][i], comp);
    }
    for(int i = 1; i <= n; i++)
        if(cop[i]) vis[i] = false;
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].need;
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].pnum;
        for(int j = 0; j < p[i].pnum; j++)
            cin >> p[i].ps[j];
    }
    min_cost.clear();
    for(int i = 0; i < 3; i++)
    {
        dfs(i, 0, 0);
    }
    printf("%d\n", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 0x73737373
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
void dfs(int now_pos, int ind, int cost, int comp)
{
    if(cost > ret) return;
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    for(int i = 1; i <= n; i++)
    {
        if(i == ind)continue;
        if(check(i) && !vis[i])
        {
            int next_cost = cost + dcost[now_pos][p[i].need] + 1;
            vis[i] = true;
            dfs(p[i].need, i, next_cost, comp + 1);
            vis[i] = false;
        }
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].need;
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].pnum;
        for(int j = 0; j < p[i].pnum; j++)
            cin >> p[i].ps[j];
    }
    for(int i = 1; i <= n; i++)
    {
        if(p[i].pnum == 0)
        {
            memset(vis, false, sizeof(vis));
            vis[i] = true;
            dfs(p[i].need, i, 1, 1);
        }
    }
    printf("%d\n", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
using namespace std;
#define INF 0x73737373
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
set <string> has[1000][3];
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
string get_state()
{
    string ret;
    for(int i = 1; i <= n; i++)
        if(vis[i])ret += i;
    return ret;
}
void dfs(int now_pos, int ind, int cost, int comp)
{
    int pos_check[3];
    memset(pos_check, 0, sizeof(pos_check));
    string state;
    if(cost >= ret) return;
    state = get_state();
    if(has[cost][now_pos].count(state)) return;
    has[cost][now_pos].insert(state);
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    for(int i = 1; i <= n; i++)
    {
        if(i == ind)continue;
        if(check(i) && !vis[i] && !pos_check[p[i].need])
        {
            int next_cost = cost + dcost[now_pos][p[i].need] + 1;
            pos_check[p[i].need] = true;
            vis[i] = true;
            dfs(p[i].need, i, next_cost, comp + 1);
            vis[i] = false;
        }
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].need;
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].pnum;
        for(int j = 0; j < p[i].pnum; j++)
            cin >> p[i].ps[j];
    }
    for(int i = 1; i <= n; i++)
    {
        if(p[i].pnum == 0)
        {
            memset(vis, false, sizeof(vis));
            vis[i] = true;
            dfs(p[i].need, i, 1, 1);
        }
    }
    printf("%d\n", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
using namespace std;
#define INF 605
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
bool all_ok()
{
    for(int i = 1; i <= n; i++)
        if(!vis[i]) return false;
    return true;
}
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
void dfs(int now_pos, int cost)
{
    while(true)
    {
        bool change = false;
        for(int i = 1; i <= n; i++)
            if(!vis[i] && p[i].need == now_pos && check(i))
            {
                vis[i] = true;
                change = true;
            }
        if(change == false) break;
    }
    if(all_ok())
    {
        ret = min(ret, cost);
        return;
    }
    int next = (now_pos + 1) % 3;
    dfs(next, cost + dcost[now_pos][next]);
}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &p[i].need);
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &p[i].pnum);
        for(int j = 0; j < p[i].pnum; j++)
            scanf("%d", &p[i].ps[j]);
    }
    for(int i = 0; i < 3; i++)
    {
        memset(vis, false, sizeof(vis));
        dfs(i, 0);
    }
    printf("%d\n", ret + n);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
using namespace std;
#define INF 605
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
set <string> has[1000][3];
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
string get_state()
{
    string ret;
    for(int i = 1; i <= n; i++)
        if(vis[i])ret += i;
    return ret;
}
void dfs(int now_pos, int cost, int comp)
{
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    if(cost >= ret || cost + n - comp >= ret) return;
    string state = get_state();
    if(has[cost][now_pos].count(state)) return;
    has[cost][now_pos].insert(state);
    bool cop[205];
    memset(cop, false, sizeof(cop));
    bool cmp = false;
    for(int i = 1; i <= n; i++)
        if(!vis[i] && p[i].need == now_pos && check(i))
        {
            comp ++;
            vis[i] = true;
            cop[i] = true;
            cmp = true;
        }
    if(!cmp)return;
    int t = 0;
    for(int i = now_pos; t < 3; i++, t++)
    {
        i %= 3;
        dfs(i, cost + dcost[now_pos][i], comp);
    }
    for(int i = 1; i <= n; i++)
        if(cop[i]) vis[i] ^= cop[i];
}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &p[i].need);
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &p[i].pnum);
        for(int j = 0; j < p[i].pnum; j++)
            scanf("%d", &p[i].ps[j]);
    }
    for(int i = 0; i < 3; i++)
        dfs(i, 0, 0);
    printf("%d\n", ret + n);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 0x73737373
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
bool has[1000][205];
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
void dfs(int now_pos, int ind, int cost, int comp)
{
    if(cost >= ret) return;
    if(has[cost][ind]) return;
    has[cost][ind] = true;
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    for(int i = 1; i <= n; i++)
    {
        if(i == ind)continue;
        if(check(i) && !vis[i])
        {
            int next_cost = cost + dcost[now_pos][p[i].need] + 1;
            vis[i] = true;
            dfs(p[i].need, i, next_cost, comp + 1);
            vis[i] = false;
        }
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].need;
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].pnum;
        for(int j = 0; j < p[i].pnum; j++)
            cin >> p[i].ps[j];
    }
    for(int i = 1; i <= n; i++)
    {
        if(p[i].pnum == 0)
        {
            memset(vis, false, sizeof(vis));
            vis[i] = true;
            dfs(p[i].need, i, 1, 1);
        }
    }
    printf("%d\n", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 0x73737373
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
bool has[1000][205][205];
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
void dfs(int now_pos, int ind, int cost, int comp)
{
    if(cost >= ret) return;
    if(has[cost][ind][comp]) return;
    has[cost][ind][comp] = true;
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    for(int i = 1; i <= n; i++)
    {
        if(i == ind)continue;
        if(check(i) && !vis[i])
        {
            int next_cost = cost + dcost[now_pos][p[i].need] + 1;
            vis[i] = true;
            dfs(p[i].need, i, next_cost, comp + 1);
            vis[i] = false;
        }
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].need;
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].pnum;
        for(int j = 0; j < p[i].pnum; j++)
            cin >> p[i].ps[j];
    }
    for(int i = 1; i <= n; i++)
    {
        if(p[i].pnum == 0)
        {
            memset(vis, false, sizeof(vis));
            vis[i] = true;
            dfs(p[i].need, i, 1, 1);
        }
    }
    printf("%d\n", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
using namespace std;
#define INF 0x73737373
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
set <string> has[1000][3];
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
string get_state()
{
    string ret;
    for(int i = 1; i <= n; i++)
        if(vis[i])ret += i;
    return ret;
}
void dfs(int now_pos, int ind, int cost, int comp)
{
    string state;
    if(cost >= ret) return;
    state = get_state();
    if(has[cost][now_pos].count(state)) return;
    has[cost][now_pos].insert(state);
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    for(int i = 1; i <= n; i++)
    {
        if(i == ind)continue;
        if(check(i) && !vis[i])
        {
            int next_cost = cost + dcost[now_pos][p[i].need] + 1;
            vis[i] = true;
            dfs(p[i].need, i, next_cost, comp + 1);
            vis[i] = false;
        }
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].need;
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].pnum;
        for(int j = 0; j < p[i].pnum; j++)
            cin >> p[i].ps[j];
    }
    for(int i = 1; i <= n; i++)
    {
        if(p[i].pnum == 0)
        {
            memset(vis, false, sizeof(vis));
            vis[i] = true;
            dfs(p[i].need, i, 1, 1);
        }
    }
    printf("%d\n", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
using namespace std;
#define INF 0x73737373
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
set <string> has[1000][3];
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
string get_state()
{
    string ret;
    for(int i = 1; i <= n; i++)
        if(vis[i])ret += i;
    return ret;
}
void dfs(int now_pos, int ind, int cost, int comp)
{
    int pos_check[3];
    memset(pos_check, 0, sizeof(pos_check));
    if(cost >= ret) return;
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    for(int i = 1; i <= n; i++)
    {
        if(i == ind)continue;
        if(check(i) && !vis[i] && !pos_check[p[i].need])
        {
            int next_cost = cost + dcost[now_pos][p[i].need] + 1;
            pos_check[p[i].need] = true;
            vis[i] = true;
            dfs(p[i].need, i, next_cost, comp + 1);
            vis[i] = false;
        }
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].need;
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].pnum;
        for(int j = 0; j < p[i].pnum; j++)
            cin >> p[i].ps[j];
    }
    for(int i = 1; i <= n; i++)
    {
        if(p[i].pnum == 0)
        {
            memset(vis, false, sizeof(vis));
            vis[i] = true;
            dfs(p[i].need, i, 1, 1);
        }
    }
    printf("%d\n", ret);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
using namespace std;
#define INF 0x73737373
const int dcost[3][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0}};
struct Part
{
    int need;
    int pnum;
    int ps[205];
}p[205];
int ret = INF, n;
bool vis[205];
set <string> has[1000][3];
set <string> ppp;
map <string, int> min_cost;
bool check(int ind)
{
    for(int i = 0; i < p[ind].pnum; i++)
    {
        int pid = p[ind].ps[i];
        if(!vis[pid]) return false;
    }
    return true;
}
string get_state()
{
    string ret;
    for(int i = 1; i <= n; i++)
        if(vis[i])ret += i;
    return ret;
}
void dfs(int now_pos, int cost, int comp)
{
    if(comp == n)
    {
        ret = min(ret, cost);
        return;
    }
    if(cost >= ret) return;
    string state = get_state();
    if(has[cost][now_pos].count(state)) return;
    has[cost][now_pos].insert(state);
    bool cop[205];
    memset(cop, false, sizeof(cop));
    bool cmp = false;
    for(int i = 1; i <= n; i++)
        if(!vis[i] && p[i].need == now_pos && check(i))
        {
            cost ++;
            comp ++;
            vis[i] = true;
            cop[i] = true;
            cmp = true;
        }
    if(!cmp)return;
    if(ppp.count(state))
    {
        if(cost <= min_cost[state])
            min_cost[state] = cost;
        else return;
    }
    else
    {
        min_cost[state] = cost;
        ppp.insert(state);
    }
    for(int i = 0; i < 3; i++)
    {
        dfs(i, cost + dcost[now_pos][i], comp);
    }
    for(int i = 1; i <= n; i++)
        if(cop[i]) vis[i] = false;
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].need;
        p[i].need--;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].pnum;
        for(int j = 0; j < p[i].pnum; j++)
            cin >> p[i].ps[j];
    }
    min_cost.clear();
    for(int i = 0; i < 3; i++)
    {
        dfs(i, 0, 0);
    }
    printf("%d\n", ret);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

int n;
int arr[210];
int A[210][210];
vector<int> vec;

int isAll(int a)
{
    int sum=0;
    for(int i=1;i<=A[a][0];i++)
    {
        if(A[a][i]==-1) sum++;
    }
    if(sum==A[a][0]) return 1;
    return 0;
}

void makeEmpty(int a)
{

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=A[i][0];j++)
        {
            if(A[i][j]==a)
            {
                A[i][j]=-1;
                if(isAll(i))
                {
                    vec.push_back(i);
                }
                break;
            }
        }
    }

}

int mrk;
int getBest(int a,int fff)
{
    int sum=0;
    for(int i=0;i<vec.size();i++)
    {
        int uu=vec[i];
        if(arr[uu]==a)
        {
            mrk=i;
            sum++;
        }
    }
    if(sum!=0 && fff)
    {
        int temp=vec[mrk];
        vec[mrk]=-1;
        mrk=temp;
    }
    return sum;
}

int cal(int gcur)
{
    int sum=0;
    //int f1=getBest(1,0);
    //int f2=getBest(2,0);
    //int f3=getBest(3,0);
    int cur=gcur;

    /*if(f1 && f2 && f3) cur=1;
    else if(f1 && f2) cur=1;
    else if(f1 && f3) cur=3;
    else if(f2 && f3) cur=2;
    else if(f1) cur=1;
    else if(f2) cur=2;
    else cur=3;*/

    while(1)
    {
        int uu=getBest(cur,1);
        //cout<<cur<<" "<<uu<<" "<<mrk<<endl;
        if(uu==0)
        {
            cur++;
            if(cur==4) cur=1;
            uu=getBest(cur,1);
            //cout<<cur<<" "<<uu<<" "<<mrk<<endl;
            if(uu==0)
            {
                cur--;
                if(cur==0) cur=3;
                cur--;
                if(cur==0) cur=3;
                uu=getBest(cur,1);
                //cout<<cur<<" "<<uu<<" "<<mrk<<endl;
                if(uu==0) return sum;
                sum=sum+2;
                makeEmpty(mrk);
            }
            else
            {
                sum++;
                makeEmpty(mrk);
            }
        }
        else
        {
            makeEmpty(mrk);
        }
    }

}

int main()
{
    int brr[210];
    int B[210][210];
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&arr[i]);
    }

    for(int i=1;i<=n;i++)
    {
        int uu;
        scanf("%d",&uu);
        A[i][0]=uu;
        for(int j=1;j<=uu;j++)
        {
            scanf("%d",&A[i][j]);
        }
        if(uu==0) vec.push_back(i);
    }
    copy(&A[0][0], &A[0][0]+210*210,&B[0][0]);
    copy(&arr[0], &arr[0]+210,&brr[0]);
    vec.clear();
    for(int i=1;i<=n;i++) if(A[i][0]==0) vec.push_back(i);
    int f1=cal(1);
    //cout<<f1<<endl;
    copy(&B[0][0], &B[0][0]+210*210,&A[0][0]);
    copy(&brr[0], &brr[0]+210,&arr[0]);
    vec.clear();
    for(int i=1;i<=n;i++) if(A[i][0]==0) vec.push_back(i);
    int f2=cal(2);
    //cout<<f2<<endl;
    copy(&B[0][0], &B[0][0]+210*210,&A[0][0]);
    copy(&brr[0], &brr[0]+210,&arr[0]);
    vec.clear();
    for(int i=1;i<=n;i++) if(A[i][0]==0) vec.push_back(i);
    int f3=cal(3);
    //cout<<f3<<endl;

    int f4=min(f1,f2);

    printf("%d\n",min(f3,f4)+n);

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

int n;
int arr[210];
int A[210][210];
vector<int> vec;

int isAll(int a)
{
    int sum=0;
    for(int i=1;i<=A[a][0];i++)
    {
        if(A[a][i]==-1) sum++;
    }
    if(sum==A[a][0]) return 1;
    return 0;
}

void makeEmpty(int a)
{

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=A[i][0];j++)
        {
            if(A[i][j]==a)
            {
                A[i][j]=-1;
                if(isAll(i))
                {
                    vec.push_back(i);
                }
                break;
            }
        }
    }

}

int mrk;
int getBest(int a,int fff)
{
    int sum=0;
    for(int i=0;i<vec.size();i++)
    {
        int uu=vec[i];
        if(arr[uu]==a)
        {
            mrk=i;
            sum++;
        }
    }
    if(sum!=0 && fff)
    {
        int temp=vec[mrk];
        vec[mrk]=-1;
        mrk=temp;
    }
    return sum;
}

int cal()
{
    int sum=0;
    int f1=getBest(1,0);
    int f2=getBest(2,0);
    int f3=getBest(3,0);
    int cur;

    if(f1 && f2 && f3) cur=1;
    else if(f1 && f2) cur=1;
    else if(f1 && f3) cur=3;
    else if(f2 && f3) cur=2;
    else if(f1) cur=1;
    else if(f2) cur=2;
    else cur=3;

    while(1)
    {
        int uu=getBest(cur,1);
        //cout<<cur<<" "<<uu<<" "<<mrk<<endl;
        if(uu==0)
        {
            cur++;
            if(cur==4) cur=1;
            uu=getBest(cur,1);
            //cout<<cur<<" "<<uu<<" "<<mrk<<endl;
            if(uu==0)
            {
                cur--;
                if(cur==0) cur=3;
                cur--;
                if(cur==0) cur=3;
                uu=getBest(cur,1);
                //cout<<cur<<" "<<uu<<" "<<mrk<<endl;
                if(uu==0) return sum;
                sum=sum+2;
                makeEmpty(mrk);
            }
            else
            {
                sum++;
                makeEmpty(mrk);
            }
        }
        else
        {
            makeEmpty(mrk);
        }
    }

}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&arr[i]);
    }

    for(int i=1;i<=n;i++)
    {
        int uu;
        scanf("%d",&uu);
        A[i][0]=uu;
        for(int j=1;j<=uu;j++)
        {
            scanf("%d",&A[i][j]);
        }
        if(uu==0) vec.push_back(i);
    }

    printf("%d\n",cal()+n);

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

int n;
int arr[210];
int A[210][210];
vector<int> vec;

int isAll(int a)
{
    int sum=0;
    for(int i=1;i<=A[a][0];i++)
    {
        if(A[a][i]==-1) sum++;
    }
    if(sum==A[a][0]) return 1;
    return 0;
}

void makeEmpty(int a)
{

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=A[i][0];j++)
        {
            if(A[i][j]==a)
            {
                A[i][j]=-1;
                if(isAll(i))
                {
                    vec.push_back(i);
                }
                break;
            }
        }
    }

}

int mrk;
int getBest(int a,int fff)
{
    int sum=0;
    for(int i=0;i<vec.size();i++)
    {
        int uu=vec[i];
        if(arr[uu]==a)
        {
            mrk=i;
            sum++;
        }
    }
    if(sum!=0 && fff)
    {
        int temp=vec[mrk];
        vec[mrk]=-1;
        mrk=temp;
    }
    return sum;
}

int cal()
{
    int sum=0;
    int f1=getBest(1,0);
    int f2=getBest(2,0);
    int f3=getBest(3,0);
    int cur;
    if(f1>=f2 && f1>=f3) cur=1;
    else if(f2>=f1 && f2>=f3) cur=2;
    else if(f3>=f2 && f3>=f1) cur=3;
    while(1)
    {
        int uu=getBest(cur,1);
        //cout<<cur<<" "<<uu<<" "<<mrk<<endl;
        if(uu==0)
        {
            cur++;
            if(cur==4) cur=1;
            uu=getBest(cur,1);
            //cout<<cur<<" "<<uu<<" "<<mrk<<endl;
            if(uu==0)
            {
                cur--;
                if(cur==0) cur=3;
                cur--;
                if(cur==0) cur=3;
                uu=getBest(cur,1);
                //cout<<cur<<" "<<uu<<" "<<mrk<<endl;
                if(uu==0) return sum;
                sum=sum+2;
                makeEmpty(mrk);
            }
            else
            {
                sum++;
                makeEmpty(mrk);
            }
        }
        else
        {
            makeEmpty(mrk);
        }
    }

}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&arr[i]);
    }

    for(int i=1;i<=n;i++)
    {
        int uu;
        scanf("%d",&uu);
        A[i][0]=uu;
        for(int j=1;j<=uu;j++)
        {
            scanf("%d",&A[i][j]);
        }
        if(uu==0) vec.push_back(i);
    }

    printf("%d\n",cal()+n);

    return 0;
}


#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<memory>
#include<cstring>
using namespace std;
const int maxn = 205;
int n,c[maxn],k[maxn],a[maxn][maxn];

bool used[maxn];
int solve(int s){
    memset(used,false,sizeof(used));
    int ans = 0,cnt = 0;
    while(true){
        for(int i=0;i<n;++i)
            if(!used[i] && c[i]==s){
                bool ff = true;
                for(int j=0;j<k[i]&&ff;++j) if(!used[a[i][j]])ff=false;
                if(ff) used[i] = true;
                ++cnt; ++ans;
            }
        if(cnt == n) return ans;
        s=(s+1)%3;
        ++ans;
    }
}

int main(){
    while(cin>>n){
        for(int i=0;i<n;++i) cin>>c[i],--c[i];
        for(int i=0;i<n;++i){
            cin>>k[i];
            for(int j=0;j<k[i];++j) cin>>a[i][j],--a[i][j];
        }
        cout<<min( solve(0), min(solve(1),solve(2) ))<<endl;
    }
    return 0;
}


#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<memory>
#include<cstring>
using namespace std;
const int maxn = 205;
int n,c[maxn],k[maxn],a[maxn][maxn];

bool used[maxn];
int solve(int s){
    memset(used,false,sizeof(used));
    for(int ans=0,cnt=0;true;s=(s+1)%3,++ans){
        int pre = cnt;
        while(1){
            for(int i=0;i<n;++i)
                if(!used[i] && c[i]==s){
                    bool ff = true;
                    for(int j=0;j<k[i]&&ff;++j) if(!used[a[i][j]])ff=false;
                    if(ff){
                        used[i] = true;
                        ++cnt; ++ans;
                    }
                }
            if(cnt == n) return ans;
            if(pre == cnt) break;
            pre = cnt;
        }
    }
}

int main(){
    while(cin>>n){
        for(int i=0;i<n;++i) cin>>c[i],--c[i];
        for(int i=0;i<n;++i){
            cin>>k[i];
            for(int j=0;j<k[i];++j) cin>>a[i][j],--a[i][j];
        }
        cout<<min( solve(0), min(solve(1),solve(2) ))<<endl;
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;

#define FOR(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define SZ(c) ((int)(c).size())

const int N = 205;
int c[N], a[N][N], na[N];
int n;
int go(int S) {
	int t=n;
	int u[N] = {}, remain=n;
	while(remain) {
		int change = 1;
		while(change) {
			change=0;
			for(int i=1;i<=n;i++) {
				if(c[i]!=S || u[i]) continue;
				int fail=0;
				for(int j=0;j<na[i];j++)
					if(!u[a[i][j]]) {fail=1;break;}
				if(!fail) {
					change=1;
					u[i]=1;
					--remain;
				}
			}
		}
		if(remain) { ++t; S = S%3+1; }
	}
	return t;
}

int main(void) {
	scanf("%d", &n);
	for(int i=1;i<=n;i++) scanf("%d", &c[i]);
	for(int i=1;i<=n;i++) {
		scanf("%d", &na[i]);
		for(int j=0;j<na[i];j++)
			scanf("%d", &a[i][j]);
	}
	int ans = 1000000;
	for(int i=1;i<=3;i++) ans = min(ans, go(i));
	printf("%d\n", ans);
	return 0;
}


#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#define maxp 1000
#define maxe 1000000
using namespace std;
struct project{
	int c,badcount;
	vector<int> s;
	vector<int> needme;
}jobs[300];
int n,deccount,mint;
queue<int> wait[3];
int main(){
	int i,t,c;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&jobs[i].c);
		jobs[i].c--;
	}
	for(i=0;i<n;i++){
		int a,j,q;
		scanf("%d",&q);
		for(j=0;j<q;j++){
			scanf("%d",&a);
			a--;
			jobs[i].s.push_back(a);
			jobs[a].needme.push_back(i);
		}
		jobs[i].badcount=jobs[i].s.size();
	}
	for(i=0;i<n;i++)
		if(!jobs[i].badcount)
			wait[jobs[i].c].push(i);
	for(deccount=c=t=0;;c++,t++){
		while(!wait[c%3].empty()){
			int k=wait[c%3].front();
			wait[c%3].pop();
			t++;deccount++;
			for(i=0;i<jobs[k].needme.size();i++){
				jobs[jobs[k].needme[i]].badcount--;
				if(jobs[jobs[k].needme[i]].badcount==0)
					wait[jobs[jobs[k].needme[i]].c].push(jobs[k].needme[i]);
			}
		}
		if(deccount==n)break;
	}
	mint=t;
	for(i=0;i<n;i++)
		jobs[i].badcount=jobs[i].s.size();
	for(i=0;i<n;i++)
		if(!jobs[i].badcount)
			wait[jobs[i].c].push(i);
	for(deccount=t=0,c=1;;c++,t++){
		while(!wait[c%3].empty()){
			int k=wait[c%3].front();
			wait[c%3].pop();
			t++;deccount++;
			for(i=0;i<jobs[k].needme.size();i++){
				jobs[jobs[k].needme[i]].badcount--;
				if(jobs[jobs[k].needme[i]].badcount==0)
					wait[jobs[jobs[k].needme[i]].c].push(jobs[k].needme[i]);
			}
		}
		if(deccount==n)break;
	}
	mint=min(t,mint);
	for(i=0;i<n;i++)
		jobs[i].badcount=jobs[i].s.size();
	for(i=0;i<n;i++)
		if(!jobs[i].badcount)
			wait[jobs[i].c].push(i);
	for(deccount=t=0,c=2;;c++,t++){
		while(!wait[c%3].empty()){
			int k=wait[c%3].front();
			wait[c%3].pop();
			t++;deccount++;
			for(i=0;i<jobs[k].needme.size();i++){
				jobs[jobs[k].needme[i]].badcount--;
				if(jobs[jobs[k].needme[i]].badcount==0)
					wait[jobs[jobs[k].needme[i]].c].push(jobs[k].needme[i]);
			}
		}
		if(deccount==n)break;
	}
	mint=min(t,mint);
	printf("%d\n",mint);
}


#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#define maxp 1000
#define maxe 1000000
using namespace std;
struct project{
	int c,badcount;
	vector<int> s;
	vector<int> needme;
}jobs[300];
int n,deccount,mint;
queue<int> wait[3];
int main(){
	freopen("in","r",stdin);
	int i,t,c;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&jobs[i].c);
		jobs[i].c--;
	}
	for(i=0;i<n;i++){
		int a,j,q;
		scanf("%d",&q);
		for(j=0;j<q;j++){
			scanf("%d",&a);
			a--;
			jobs[i].s.push_back(a);
			jobs[a].needme.push_back(i);
		}
		jobs[i].badcount=jobs[i].s.size();
	}
	for(i=0;i<n;i++)
		if(!jobs[i].badcount)
			wait[jobs[i].c].push(i);
	for(deccount=c=t=0;;c++,t++){
		while(!wait[c%3].empty()){
			int k=wait[c%3].front();
			wait[c%3].pop();
			t++;deccount++;
			for(i=0;i<jobs[k].needme.size();i++){
				jobs[jobs[k].needme[i]].badcount--;
				if(jobs[jobs[k].needme[i]].badcount==0)
					wait[jobs[jobs[k].needme[i]].c].push(jobs[k].needme[i]);
			}
		}
		if(deccount==n)break;
	}
	mint=t;
	for(i=0;i<n;i++)
		jobs[i].badcount=jobs[i].s.size();
	for(i=0;i<n;i++)
		if(!jobs[i].badcount)
			wait[jobs[i].c].push(i);
	for(deccount=t=0,c=1;;c++,t++){
		while(!wait[c%3].empty()){
			int k=wait[c%3].front();
			wait[c%3].pop();
			t++;deccount++;
			for(i=0;i<jobs[k].needme.size();i++){
				jobs[jobs[k].needme[i]].badcount--;
				if(jobs[jobs[k].needme[i]].badcount==0)
					wait[jobs[jobs[k].needme[i]].c].push(jobs[k].needme[i]);
			}
		}
		if(deccount==n)break;
	}
	mint=min(t,mint);
	for(i=0;i<n;i++)
		jobs[i].badcount=jobs[i].s.size();
	for(i=0;i<n;i++)
		if(!jobs[i].badcount)
			wait[jobs[i].c].push(i);
	for(deccount=t=0,c=2;;c++,t++){
		while(!wait[c%3].empty()){
			int k=wait[c%3].front();
			wait[c%3].pop();
			t++;deccount++;
			for(i=0;i<jobs[k].needme.size();i++){
				jobs[jobs[k].needme[i]].badcount--;
				if(jobs[jobs[k].needme[i]].badcount==0)
					wait[jobs[jobs[k].needme[i]].c].push(jobs[k].needme[i]);
			}
		}
		if(deccount==n)break;
	}
	mint=min(t,mint);
	printf("%d\n",mint);
}


/*******************\
|* # By longbiau # *|
\*******************/

// #include C {
#include<cstring>
#include<cassert>
#include<cstdio>
#include<cctype>
#include<cmath>
// }

// #include C++ {
#include<functional>
#include<algorithm>
#include<iostream>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<list>
#include<map>
#include<set>
// }
using namespace std;
// #typedef {
typedef long long int64;
typedef unsigned long long uint64;
typedef pair <int, int> PII;
typedef pair <int64, int64> PLL;
typedef pair <char, char> PCC;
typedef pair <double, double> PDD;
// }
#ifndef ONLINE_JUDGE
// #parameter{
#define TYPE decltype
/////////////////////////////////////////////////////////////
#else
/////////////////////////////////////////////////////////////
#define TYPE __typeof
// }
#endif
// #define {
#define MP make_pair
#define PB push_back
#define SZ(a) ((int)(a).size())
#define X first
#define Y second
#define L(x) ((x) * 2 )
#define R(x) ((x) * 2 + 1)
#define max3(x, y, z) (max(max((x), (y)), (z)))
#define min3(x, y, z) (min(min((x), (y)), (z)))
#define BIT(x, i) (((x) >> (i)) & 1)
#define FOR(it, c) for( TYPE((c).begin()) it = (c).begin(); it != (c).end(); it++)
/////////////////////////////////////////////////////////////
const double PI = 2.0*acos(0.0);
const double EPS = 1e-6;

#define GREATER(x, y) ((x) > (y) + EPS)
#define GREATER_EQUAL(x, y) ((x) > (y) - EPS)
#define LESS(x, y) ((x) < (y) - EPS)
#define LESS_EQUAL(x, y) ((x) < (y) + EPS)
#define EQUAL(x, y) (abs((x) - (y)) < EPS)

#define MAX_N 205
#define MAXX 0x7f
#define MAX 205
#define UPPER 2147483647LL
#define INF (1<<29)
#define NONE -1
#define NIL 0
// }

/////////////////////////////////////////////////////////////
int c[MAX_N];
vector <int> G[MAX_N];
int indeg[MAX_N];
/////////////////////////////////////////////////////////////
int main(){
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif

    int n;
    scanf("%d", &n);
    for(int i=1; i<=n; i++)
        scanf("%d", c+i);
    for(int i=1; i<=n; i++){
        int k;
        scanf("%d", &k);
        indeg[i] = k;
        while(k--){
            int a;
            scanf("%d", &a);
            G[a].PB(i);
        }
    }
    int comp = 3;
    vector <int> list[4];
    for(int v=1; v<=n; v++)
        if(indeg[v] == 0){
            comp = min(comp, c[v]);
            list[c[v]].PB(v);
        }
    int hour = 0;
    while(SZ(list[1]) > 0 || SZ(list[2]) > 0 || SZ(list[3]) > 0){
        vector <int> work = list[comp];
        list[comp].clear();
        if(SZ(work) > 0){
            FOR(uptr, work){
                FOR(vptr, G[*uptr])
                    if(--indeg[*vptr] == 0)
                        list[c[*vptr]].PB(*vptr);
            }
        }else{
            hour++;
            if(++comp > 3)
                comp = 1;
        }
    }
    printf("%d\n", hour+n);
    return 0;
}


/*******************\
|* # By longbiau # *|
\*******************/

// #include C {
#include<cstring>
#include<cassert>
#include<cstdio>
#include<cctype>
#include<cmath>
// }

// #include C++ {
#include<functional>
#include<algorithm>
#include<iostream>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<list>
#include<map>
#include<set>
// }
using namespace std;
// #typedef {
typedef long long int64;
typedef unsigned long long uint64;
typedef pair <int, int> PII;
typedef pair <int64, int64> PLL;
typedef pair <char, char> PCC;
typedef pair <double, double> PDD;
// }
#ifndef ONLINE_JUDGE
// #parameter{
#define TYPE decltype
/////////////////////////////////////////////////////////////
#else
/////////////////////////////////////////////////////////////
#define TYPE __typeof
// }
#endif
// #define {
#define MP make_pair
#define PB push_back
#define SZ(a) ((int)(a).size())
#define X first
#define Y second
#define L(x) ((x) * 2 )
#define R(x) ((x) * 2 + 1)
#define max3(x, y, z) (max(max((x), (y)), (z)))
#define min3(x, y, z) (min(min((x), (y)), (z)))
#define BIT(x, i) (((x) >> (i)) & 1)
#define FOR(it, c) for( TYPE((c).begin()) it = (c).begin(); it != (c).end(); it++)
/////////////////////////////////////////////////////////////
const double PI = 2.0*acos(0.0);
const double EPS = 1e-6;

#define GREATER(x, y) ((x) > (y) + EPS)
#define GREATER_EQUAL(x, y) ((x) > (y) - EPS)
#define LESS(x, y) ((x) < (y) - EPS)
#define LESS_EQUAL(x, y) ((x) < (y) + EPS)
#define EQUAL(x, y) (abs((x) - (y)) < EPS)

#define MAX_N 205
#define MAXX 0x7f
#define MAX 205
#define UPPER 2147483647LL
#define INF (1<<29)
#define NONE -1
#define NIL 0
// }

/////////////////////////////////////////////////////////////
int c[MAX_N];
vector <int> G[MAX_N];
int indeg[MAX_N];
int solve(vector <int> list[], int comp){
    int hour = 0;
    int tmp_indeg[MAX_N];
    memcpy(tmp_indeg, indeg, sizeof(tmp_indeg));
    while(SZ(list[1]) > 0 || SZ(list[2]) > 0 || SZ(list[3]) > 0){
        if(SZ(list[comp]) > 0){
            vector <int> work = list[comp];
            list[comp].clear();
            FOR(uptr, work){
                FOR(vptr, G[*uptr])
                    if(--tmp_indeg[*vptr] == 0)
                        list[c[*vptr]].PB(*vptr);
            }
        }else{
            hour++;
            if(++comp > 3)
                comp = 1;
        }
    }
    return hour;
}
/////////////////////////////////////////////////////////////
int main(){
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif

    int n;
    scanf("%d", &n);
    for(int i=1; i<=n; i++)
        scanf("%d", c+i);
    for(int i=1; i<=n; i++){
        int k;
        scanf("%d", &k);
        indeg[i] = k;
        while(k--){
            int a;
            scanf("%d", &a);
            G[a].PB(i);
        }
    }
    vector <int> list[4];
    for(int v=1; v<=n; v++)
        if(indeg[v] == 0)
            list[c[v]].PB(v);
    int hour = INF;
    for(int k=1; k<=3; k++){
        vector <int> start[4];
        for(int j=0; j<4; j++)
            start[j] = list[j];
        hour = min(hour, solve(start, k));
    }
    printf("%d\n", hour+n);
    return 0;
}