/*
Author: baodat
※\(^o^)/※
Current goal: Training for VNOI shirt
*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long int
#define FOR(i, l, r) for(int i = l; i <= r; i++)
#define FORD(i, l, r) for(int i = l; i >= r; i--)
#define db double
#define ldb long double
#define all_1(x) (x).begin() + 1, (x).end()
#define all(x) (x).begin(), (x).end()
#define ins insert
#define pb push_back
template<typename T>void debug_var(const T& var, const string& name){
cerr << name << ": " << var << "\n";
}
template<typename T>void debug_1d(const T& vt, const string& name){
if(vt.empty()){
cerr << name << " is empty!\n";
return;
}
FOR(i, 0, (int)vt.size() - 1){
cerr << name << "[" << i << "]: " << vt[i] << "\n";
}
}
const ll oo = 2e18;
const int N = 2e5 + 5;
struct Data{
ll a, b;
};
struct segment_tree{
int _n;
vector<int> _st;
segment_tree(int n = 0){
init(n);
}
void init(int n){
_n = n;
_st.assign(4 * _n + 5, 0);
}
void update(int i, int l, int r, int pos, int val){
if(l == r){
_st[i] = val;
return;
}
int m = (l + r) >> 1, cl = (i << 1), cr = (cl | 1);
if(pos <= m)update(cl, l, m, pos, val);
else update(cr, m + 1, r, pos, val);
_st[i] = max(_st[cl], _st[cr]);
}
int query(int i, int l, int r, int u, int v){
if(l > v || r < u) return 0;
if(l >= u && r <= v) return _st[i];
int m = (l + r) >> 1, cl = (i << 1), cr = (cl | 1);
return max(query(cl, l, m, u, v), query(cr, m + 1, r, u, v));
}
};
vector<int> comp;
int get(int x){
return lower_bound(all(comp), x) - comp.begin() + 1;
}
struct node{
int cl, cr, cnt;
}pst[40 * N];
int root[N];
int amount_node = 0;
int build(int l, int r){
int i = ++amount_node;
if(l == r){
return i;
}
int m = (l + r) >> 1;
pst[i].cl = build(l, m);
pst[i].cr = build(m + 1, r);
return i;
}
int update(int prv_ver, int l, int r, int pos){
int i = ++amount_node;
pst[i] = pst[prv_ver];
++pst[i].cnt;
if(l == r) return i;
int m = (l + r) >> 1;
if(pos <= m) pst[i].cl = update(pst[prv_ver].cl, l, m, pos);
else pst[i].cr = update(pst[prv_ver].cr, m + 1, r, pos);
return i;
}
int query(int i, int l, int r, int u, int v){
if(l > v || r < u) return 0;
if(l >= u && r <= v) return pst[i].cnt;
int m = (l + r) >> 1;
return query(pst[i].cl, l, m, u, v) + query(pst[i].cr, m + 1, r, u, v);
}
void solve(){
int n, q;
cin >> n >> q;
vector<Data>a(n + 1);
FOR(i, 1, n) cin >> a[i].a >> a[i].b;
vector<int> queries(q + 1);
FOR(i, 1, q) cin >> queries[i];
FOR(i, 1, n){
comp.pb(min(a[i].a, a[i].b));
comp.pb(max(a[i].a, a[i].b));
comp.pb(max(a[i].a, a[i].b) - 1);
}
FOR(i, 1, q) comp.pb(queries[i]);
sort(all(comp));
int sz = comp.size();
comp.erase(unique(all(comp)), comp.end());
segment_tree st(sz + 1);
FOR(i, 1, q) st.update(1, 1, sz, get(queries[i]), i);
vector<int> R(n + 1);
FOR(i, 1, n) R[i] = st.query(1, 1, sz, get(min(a[i].a, a[i].b)), get(max(a[i].a, a[i].b) - 1));
//debug_1d(R, "righttest");
root[0] = build(1, sz);
FOR(i, 1, q) root[i] = update(root[i - 1], 1, sz, get(queries[i]));
ll ans = 0;
FOR(i, 1, n){
int cnt = query(root[q], 1, sz, get(max(a[i].a, a[i].b)), sz) - query(root[R[i]], 1, sz, get(max(a[i].a, a[i].b)), sz);
if (R[i] == 0) {
if (cnt & 1) ans += a[i].b;
else ans += a[i].a;
}
else {
if (cnt & 1) ans += min(a[i].a, a[i].b);
else ans += max(a[i].a, a[i].b);
}
}
cout << ans << "\n";
}
/*notes
ok so first thing is we just care the amount of time each a got flipped
and we know it's current state
let it be cnt_i
and then? if cnt_i & 1 -> mean it got flipped
n, k <= 2e5 so maybe log^2 would pass
ok actually nvm that wouldn' work
ok now what if op_i < min(a_i, b_i)? then it can't change anything
what if op_i >= max(a_i, b_i) mean it's always change
and min(a_i, b_i) <= op_i < max(a_i, b_i) always change to bigger
so if this operation happen, then it always face the largest card
anything prior is just wiped
ok cool the idea is simplier now
oh so it's just basically
find the rightest min(a_i, b_i) <= op_i < max(a_i, b_i), and then count the amount of op_i such that >= max(a_i, b_i)
we can use bit to count max(a_i, b_i)
what about max(a_i, b_i) > op_i >= min(a_i, b_i)
ok what about the rightest
let try solve it first
It's easier, if we move backward, then for this, which card satisfy? We can for all the active cards but that maybe way too sow
query (1, 1, n, min(a_i, b_i), max(a_i, b_i) - 1) -> what is the farthest
we build max segment tree
oh so basically we can update the operation i
st.update(1, 1, n, queries[i], i)
ok done so now count the amount of elements that is op_i >= max(a_i, b_i)
we can try pst this
ok each seg tree is the frequency of max(a_i, b_i)
so the answer is basically root[n] - root[op_i]
*/
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int t = 1;
//cin >> t;
while(t--){
solve();
}
return 0;
}