#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
template<typename T> using ordered_set = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
struct segtree {
vector<int> tree;
int offset = 1;
segtree(int n) {
while (offset < n) offset *= 2;
tree.resize(offset*2, -1);
}
void update(int i, int x) {
tree[i + offset] = max(tree[i + offset], x);
i += offset;
while (i >>= 1) tree[i] = max(tree[2*i], tree[2*i + 1]);
}
int query(int v, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return tree[v];
if (qr < l || r < ql) return -1;
int mid = (l+r)/2;
return max(query(2*v, l, mid, ql, qr),
query(2*v+1, mid+1, r, ql, qr));
}
int query(int l, int r) { return query(1, 0, offset - 1, l, r); }
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m; cin >> n >> m;
pair<int,int> paint[n];
int frame[m];
for (auto& [v, s] : paint) cin >> s >> v;
for (int& f : frame) cin >> f;
map<int, vector<int*>> comp;
for (int i = 0; i < n; i++) {
auto& [v, s] = paint[i];
comp[v].push_back(&v);
comp[s].push_back(&s);
}
for (int i = 0; i < m; i++) {
comp[frame[i]].push_back(&frame[i]);
}
int z = 0;
for (auto [_, list] : comp) {
for (auto i : list) {
*i = z;
}
z++;
}
sort(paint, paint + n, greater<>());
sort(frame, frame + m);
int dp[n], ans = 0;
segtree s(600'001);
for (int i = 0; i < n; i++) {
auto [vi, si] = paint[i];
int bound = lower_bound(frame, frame + m, si) - frame;
bound = m-1 - bound;
dp[i] = min(bound, 1 + s.query(vi, 600'000));
ans = max(ans, 1 + dp[i]);
s.update(vi, dp[i]);
// cout<<vi << " " << si<<' '<<bound<<" : " << dp[i]<<'\n';
}
cout << ans;
}