rt
#include<iostream>
#include<algorithm>
using namespace std;
const int upest=1e7;
int n,m,siz,X1,Y1,X2,Y2,root[500001],L,R;
struct point{
int x,y;
}d[500001];
bool cmp(point x,point y)
{
if(x.x==y.x)
return x.y<y.y;
return x.x<y.x;
}
int lower_bound(int x)
{
int l=1,r=n,mid;
while(l<r)
{
mid=l+r>>1;
if(d[mid].x>=x)
r=mid;
else
l=mid+1;
}
return r;
}
int upper_bound(int x)
{
int l=1,r=n,mid;
while(l<r)
{
mid=l+r+1>>1;
if(d[mid].x<=x)
l=mid;
else
r=mid-1;
}
return l;
}
struct tree{
int ls,rs,v;
}t[20*500000+5];
void upda(int&p,int P,int pl,int pr,int id)
{
p=++siz;
t[p]=t[P];
++t[p].v;
if(pl==pr)
return;
int mid=pl+pr>>1;
if(mid>=pl)
upda(t[p].ls,t[P].ls,pl,mid,id);
else
upda(t[p].rs,t[P].rs,mid+1,pr,id);
}
int query(int l,int r,int p1,int p2,int pl,int pr)
{
if(l<=pl&&pr<=r)
return t[p2].v-t[p1].v;
int mid=pl+pr>>1,s=0;
if(mid>=l)
s+=query(l,r,t[p1].ls,t[p2].ls,pl,mid);
if(mid<r)
s+=query(l,r,t[p1].rs,t[p2].rs,mid+1,pr);
return s;
}
main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;++i)
cin>>d[i].x>>d[i].y;
sort(d+1,d+n+1,cmp);
for(int i=1;i<=n;++i)
upda(root[i],root[i-1],0,upest,d[i].y);
for(int i=1;i<=m;++i)
{
cin>>X1>>Y1>>X2>>Y2;
cout<<query(Y1,Y2,root[lower_bound(X1)-1],root[upper_bound(X2)],0,upest)<<'\n';
}
}