#include <bits/stdc++.h>
using namespace std;
const int MAXN = 310;
struct Bigrpah {
  bool g[MAXN][MAXN];
  int n;
  bool visy[MAXN];
  int match[MAXN];
  void init(int _n) {
    n = _n;
    memset(g, false, sizeof(g));
  }
  bool find(int i) {
    for (int j = 0; j < n; j++)
      if (g[i][j] && !visy[j]) {
        visy[j] = true;
        if (match[j] == -1 || find(match[j])) {
          match[j] = i;
          return true;
        }
      }
    return false;
  }
  int find_match() {
    memset(match, -1, sizeof(match));
    int ans = 0;
    for (int i = 0; i < n; i++) {
      memset(visy, false, sizeof(visy));
      if (find(i)) ans++;
    }
    return ans;
  }
} bg;
const long long INFI = 1LL << 44;
struct Net {
  struct Edge {
    int to;
    long long c, f;
    Edge *next, *rev;
    Edge() {
      to = f = c = 0;
      next = rev = NULL;
    }
    Edge(int to, long long c, long long f, Edge* next)
        : to(to), c(c), f(f), next(next), rev(NULL) {}
  };
  int n;
  vector<Edge*> edge;
  vector<int> mark;
  int gmark;
  Net() { edge.clear(); }
  void init(int _n) {
    n = _n;
    edge.clear();
    for (int i = 0; i < (int)n; i++) edge.push_back(NULL);
  }
  void _add_edge(int a, int b, long long c, long long f) {
    edge[a] = new Edge(b, c, f, edge[a]);
  }
  void add_edge(int a, int b, long long c) {
    if (a == b) return;
    _add_edge(a, b, c, 0);
    _add_edge(b, a, c, c);
    edge[a]->rev = edge[b];
    edge[b]->rev = edge[a];
  }
  long long aug(int i, int t, long long bound, long long curr) {
    if (mark[i] == gmark) return 0;
    if (i == t) return curr;
    mark[i] = gmark;
    for (Edge* ptr = edge[i]; ptr; ptr = ptr->next) {
      if (ptr->c - ptr->f >= bound) {
        long long flow = aug(ptr->to, t, bound, min(curr, ptr->c - ptr->f));
        if (flow > 0) {
          ptr->f += flow;
          ptr->rev->f -= flow;
          return flow;
        }
      }
    }
    return 0;
  }
  long long find_maxflow(int s, int t) {
    long long bound = 0;
    for (Edge* ptr = edge[s]; ptr; ptr = ptr->next) bound += ptr->c - ptr->f;
    mark = vector<int>(n, 0);
    gmark = 100;
    long long res = 0;
    for (; bound; bound /= 2) {
      gmark++;
      long long tmp;
      while ((tmp = aug(s, t, bound, INFI)) > 0) {
        gmark++;
        res += tmp;
      }
    }
    return res;
  }
} net;
int n;
int main() {
  cin >> n;
  bg.init(n);
  for (int i = 0; i < n; i++) {
    int c;
    cin >> c;
    for (int j = 0; j < c; j++) {
      int k;
      cin >> k;
      bg.g[i][k - 1] = true;
    }
  }
  bg.find_match();
  int S = n, T = n + 1;
  net.init(n + 2);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (bg.g[i][j])
        if (bg.match[j] != i) net.add_edge(i, bg.match[j], INFI);
  long long sum = 0;
  for (int i = 0; i < (int)n; i++) {
    int w;
    cin >> w;
    w = -w;
    if (w > 0) {
      sum += w;
      net.add_edge(S, i, w);
    } else {
      net.add_edge(i, T, -w);
    }
  }
  long long ans = sum - net.find_maxflow(S, T);
  ans = -ans;
  cout << ans << endl;
}
