#include <bits/stdc++.h>
using namespace std;
template <typename T>
string tostr(const T& t) {
  ostringstream os;
  os << t;
  return os.str();
}
int N;
int dist[5][5];
typedef struct {
  int c;
  vector<int> dep;
} typepart;
vector<typepart> P;
int calc(int at) {
  set<int> have;
  int tot = 0;
  for (int i = (int)(0); i <= (int)(N - 1); ++i) {
    int mntime = 9999999;
    int which = -1;
    for (int j = (int)(0); j <= (int)(N - 1); ++j) {
      if (have.count(j)) continue;
      bool haveall = true;
      for (int k = (int)(0); k <= (int)((int)P[j].dep.size() - 1); ++k) {
        if (!have.count(P[j].dep[k])) {
          haveall = false;
          break;
        }
      }
      if (haveall) {
        if (dist[at][P[j].c] < mntime) {
          mntime = dist[at][P[j].c];
          which = j;
        }
      }
    }
    tot += mntime + 1;
    have.insert(which);
    at = P[which].c;
  }
  return tot;
}
int main() {
  memset(dist, 0, sizeof dist);
  dist[0][1] = 1;
  dist[1][0] = 2;
  dist[0][2] = 2;
  dist[2][0] = 1;
  dist[1][2] = 1;
  dist[2][1] = 2;
  cin >> N;
  P.resize(N);
  for (int i = (int)(0); i <= (int)(N - 1); ++i) {
    cin >> P[i].c;
    --P[i].c;
    P[i].dep.clear();
  }
  for (int i = (int)(0); i <= (int)(N - 1); ++i) {
    int n;
    cin >> n;
    for (int j = (int)(0); j <= (int)(n - 1); ++j) {
      int x;
      cin >> x;
      P[i].dep.push_back(x - 1);
    }
  }
  int best = 9999999;
  best = min(best, calc(0));
  best = min(best, calc(1));
  best = min(best, calc(2));
  cout << best << endl;
  return 0;
}
