#include <bits/stdc++.h>
const int oo = 0x3f3f3f3f;
using std::vector;
const int MAXN = 305;
namespace Dinic {
const int MAXV = 1e3 + 5, MAXE = 2e6 + 5;
struct Edge {
  int u, v;
  int rsd;
  int next;
  Edge() {}
  Edge(int u_, int v_, int c_, int next_)
      : u(u_), v(v_), rsd(c_), next(next_) {}
};
int n, m, s, t;
int head[MAXV];
Edge edge[MAXE];
int dis[MAXV];
int cur[MAXV];
inline void init(int size) {
  n = size + 2;
  s = size;
  t = size + 1;
  m = 0;
  memset(head, -1, n * sizeof(*head));
}
inline void addEdge(int u, int v, int c) {
  edge[m] = Edge(u, v, c, head[u]);
  head[u] = m++;
  edge[m] = Edge(v, u, 0, head[v]);
  head[v] = m++;
}
bool bfs() {
  static int q[MAXV];
  int front = 0, rear = 0;
  memset(dis, -1, n * sizeof(*dis));
  dis[s] = 0;
  q[rear++] = s;
  while (front != rear) {
    int u = q[front++];
    for (int i = head[u]; i >= 0; i = edge[i].next) {
      const Edge &e = edge[i];
      if (dis[e.v] < 0 && e.rsd > 0) {
        dis[e.v] = dis[e.u] + 1;
        q[rear++] = e.v;
      }
    }
  }
  return dis[t] >= 0;
}
int dfs(int u, int rsd) {
  if (u == t || rsd == 0) return rsd;
  int res = 0;
  for (int &i = cur[u]; i >= 0; i = edge[i].next) {
    Edge &e = edge[i];
    if (dis[u] + 1 == dis[e.v] && e.rsd > 0) {
      int f = dfs(e.v, std::min(e.rsd, rsd));
      if (f > 0) {
        e.rsd -= f;
        edge[i ^ 1].rsd += f;
        res += f;
        rsd -= f;
        if (rsd == 0) return res;
      }
    }
  }
  return res;
}
int exec() {
  int flow = 0;
  while (bfs()) {
    memcpy(cur, head, n * sizeof(*cur));
    flow += dfs(s, +oo);
  }
  return flow;
}
}  // namespace Dinic
int n;
vector<int> set[MAXN];
int weight[MAXN];
void input() {
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    int m;
    scanf("%d", &m);
    for (int j = 0; j < m; ++j) {
      int first;
      scanf("%d", &first);
      set[i].push_back(first - 1);
    }
  }
  for (int i = 0; i < n; ++i) {
    scanf("%d", &weight[i]);
  }
}
void solve() {
  for (int i = 0; i < n; ++i) {
    weight[i] = -weight[i];
  }
  using namespace Dinic;
  init(2 * ::n);
  for (int i = 0; i < ::n; ++i) {
    addEdge(s, i, 1);
    addEdge(::n + i, t, 1);
    for (size_t j = 0; j < set[i].size(); ++j) {
      addEdge(i, ::n + set[i][j], 1);
    }
  }
  assert(exec() == ::n);
  static int match[MAXN];
  for (int i = 0; i < ::n; ++i) {
    for (int j = head[i]; j; j = edge[j].next) {
      if (edge[j].rsd == 0) {
        match[edge[j].v - ::n] = i;
        break;
      }
    }
  }
  int ans = 0;
  init(::n);
  for (int i = 0; i < ::n; ++i) {
    if (weight[i] >= 0) {
      ans += weight[i];
      addEdge(s, i, weight[i]);
    } else {
      addEdge(i, t, -weight[i]);
    }
    for (int j = 0; j < set[i].size(); ++j) {
      addEdge(i, match[set[i][j]], +oo);
    }
  }
  ans -= exec();
  ans = -ans;
  printf("%d\n", ans);
}
int main() {
  input();
  solve();
}
