#include <cstdio>
#include <cstring>
#include <cstdlib>
#include<algorithm>
using namespace std;
const int MAXN = 100005;
const int MOD = 2147483647;
struct Node
{
int left; //左子树
int right; //右子树
int size; //大小
int val; //值
int key; //平衡种子
}tree[MAXN];
struct node{
int x;
int y;
}a[MAXN],b[MAXN];
bool cmp(node a,node b){
if(a.y == b.y ){
return a.x > b.x ;
}
return a.y >b.y ;
}
int root,tot;
int add(int val){
tot++;
tree[tot].size = 1;
tree[tot].val = val;
tree[tot].key = rand()%MOD;
tree[tot].left = 0;
tree[tot].right = 0;
return tot;
}
void update_root(int now){
int left,right;
left = tree[now].left;
right = tree[now].right;
tree[now].size = tree[left].size + tree[right].size + 1;
}
//拆分(now原treap,a左子树,b右子树,val值)
void split_new(int now, int &a, int &b, int val){
if(now == 0){
a = 0;
b = 0;
return;
}
if(tree[now].val <= val){//now左子树中的所有值都小于now,
a = now;
split_new(tree[now].right, tree[a].right, b, val);
}else{
b = now;
split_new(tree[now].left, a, tree[b].left, val);
}
update_root(now);
}//按权值aplit
void merge_new(int &now, int a, int b){
if(a==0 || b==0){
now = a+b;
return;
}//某节点为空直接返回另一节点,合并结束
//按照key值合并(堆性质)
if(tree[a].key<tree[b].key){
/**
* a树key值小于b树,那么b树属于a树的后代,因为b树恒大于a树,那么b树一定属于a树的右后代,
* a的左子树不变,直接赋给now,递归合并a的右子树和b
*/
now = a;
merge_new(tree[now].right, tree[a].right, b);//b加到a的右后代上,a的右子树与y合并
}else{
//a的key值大于b树,b的左子树与a合并
now = b;
merge_new(tree[now].left, a, tree[b].left);
}
update_root(now);
}
int find_new(int now, int rank){//找第k大
// if(rank==0){
// return 0;
// }超时原因之一
while (tree[tree[now].left].size+1 != rank){
if(tree[tree[now].left].size >= rank){
now = tree[now].left;
}else{
rank -= tree[tree[now].left].size + 1;
now = tree[now].right;
}
}
return tree[now].val;
//printf("%d\n", tree[now].val);
}
void insert_new(int val){
int x,y,z;
x = 0;
y = 0;
z = add(val);
split_new(root, x, y, val);
merge_new(x,x,z);
merge_new(root, x, y);
}
void del_new(int val){
int x,y,z;
x = y = z = 0;
split_new(root, x, y, val);
split_new(x, x, z, val-1);
merge_new(z, tree[z].left, tree[z].right);
merge_new(x, x, z);
merge_new(root, x, y);
}
int get_next(int val){
int x,y;
x = y = 0;
split_new(root,x,y,val);
int u=find_new(y,1);
merge_new(root,x,y);
return u;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
memset(tree,0,sizeof(tree));
int s;
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].x ,&a[i].y );
}
for(int j=1;j<=m;j++){
scanf("%d%d",&b[j].x ,&b[j].y);
}
sort(a+1,a+1+n,cmp);
sort(b+1,b+1+m,cmp);
// for(int i=1;i<=m;i++){
// printf("%d^^\n",b[i].y );
// }
long long sum;
int k=1;
int u;
sum=0;
for(int i=1;i<=n;i++){
while(b[k].y>=a[i].y&&k<=m){
insert_new(b[k].x);
k++;
}
s=0;
u=a[i].x;
u--;
s=get_next(u);
if(!s){
printf("-1\n");
return 0;
}
sum+=s;
del_new(s);
}
printf("%lld",sum);
return 0;
}