#include <bits/stdc++.h>
#pragma GCC target("avx2,avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
constexpr char ln = '\n';
template <class T1, class T2>
inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T1, class T2>
inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
inline int topbit(int x) { return x == 0 ? -1 : 31 - __builtin_clz(x); }
inline int topbit(long long x) { return x == 0 ? -1 : 63 - __builtin_clzll(x); }
inline int botbit(int x) { return x == 0 ? 32 : __builtin_ctz(x); }
inline int botbit(long long x) { return x == 0 ? 64 : __builtin_ctzll(x); }
inline int popcount(int x) { return __builtin_popcount(x); }
inline int popcount(long long x) { return __builtin_popcountll(x); }
inline int kthbit(long long x, int k) { return (x >> k) & 1; }
inline void print() { cout << "\n"; }
template <class T>
inline void print(const vector<T> &v) {
  for (auto itr = v.begin(); itr != v.end(); ++itr) cout << *itr << " ";
  print();
}
template <class T, class... Args>
inline void print(const T &x, const Args &...args) {
  cout << x << " ";
  print(args...);
}
inline void debug() {}
template <class T>
inline void debug(const vector<T> &v) {}
template <class T, class... Args>
inline void debug(const T &x, const Args &...args) {}
struct Fast_ios {
  Fast_ios() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  };
} fast_ios;
struct UnionFind {
  int N;
  vector<int> node;
  UnionFind() {}
  UnionFind(int N) : N(N), node(N, -1) {}
  void init(int x) {
    node.assign(x, -1);
    N = x;
  }
  bool merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (node[x] > node[y]) swap(x, y);
    node[x] += node[y];
    node[y] = x;
    N--;
    return true;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int root(int x) {
    if (node[x] < 0) return x;
    return node[x] = root(node[x]);
  }
  int size(int x) { return -node[root(x)]; }
  int count() const { return N; }
};
template <typename T>
struct edge {
  int src, to;
  T cost;
  int id;
  edge() {}
  edge(int to, T cost) : src(-1), to(to), cost(cost), id(-1) {}
  edge(int src, int to, T cost) : src(src), to(to), cost(cost), id(-1) {}
  edge(int src, int to, T cost, int id)
      : src(src), to(to), cost(cost), id(id) {}
  bool operator<(const edge &e) const { return cost < e.cost; }
};
int main() {
  int M, N;
  cin >> M >> N;
  vector<ll> A(M), B(N);
  for (int i = 0; i < (M); ++i) cin >> A[i];
  for (int i = 0; i < (N); ++i) cin >> B[i];
  vector<edge<ll>> E;
  ll ans = 0;
  for (int i = 0; i < (M); ++i) {
    int cnt;
    cin >> cnt;
    for (int j = 0; j < (cnt); ++j) {
      int v;
      cin >> v;
      v--;
      E.emplace_back(i, v + M, A[i] + B[v]);
      ans += A[i] + B[v];
    }
  }
  sort((E).begin(), (E).end());
  reverse((E).begin(), (E).end());
  UnionFind uf(N + M);
  for (auto &e : E) {
    if (uf.merge(e.src, e.to)) {
      ans -= e.cost;
    }
  }
  cout << ans << ln;
}
