# 【PA2011】Kangaroos

Description

N<=50000,M<=200000
Input

Output

Sample Input

3 3

2 5

1 3

6 6

3 5

1 10

7 9
Sample Output

2

3

0
HINT

Source

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 200010
#define Dnum 2
#define GET (ch>='0'&&ch<='9')
using namespace std;
inline void in(int &x)
{
char ch=getchar();x=0;
while (!GET)    ch=getchar();
while (GET) x=x*10+ch-'0',ch=getchar();
}
int n,m,root;
bool cmp_d;
int id[MAXN],x[MAXN],y[MAXN];
struct KDtree
{
int ch[2],f,d[Dnum],minn[Dnum],maxn[Dnum],maxv[Dnum],maxt[Dnum],mint;
inline void init()  {   for (int i=0;i<Dnum;++i)    minn[i]=maxn[i]=d[i],maxv[i]=maxt[i]=0; }
inline bool operator < (const KDtree& a)const   {   return d[cmp_d]<a.d[cmp_d]; }
}tree[MAXN];
inline void add(int rt,int x,int y)
{
if (~x)
{
if (~tree[rt].mint)    tree[rt].maxv[0]=max(tree[rt].maxv[0],x-tree[rt].maxt[0]-1);
else    tree[rt].mint=x;
tree[rt].maxv[1]=max(tree[rt].maxv[1],x-tree[rt].maxt[1]-1);
tree[rt].maxt[0]=tree[rt].maxt[1]=y;
}
}
inline void push_up(int rt)
{
for (int x=0,i=0;i<2;++i)
if ((x=tree[rt].ch[i]))
for (int j=0;j<Dnum;++j)
tree[rt].minn[j]=min(tree[rt].minn[j],tree[x].minn[j]),
tree[rt].maxn[j]=max(tree[rt].maxn[j],tree[x].maxn[j]);
}
inline void push_down(int rt)
{
int x=tree[rt].mint,y=tree[rt].maxt[0];
for (int i=0,j=0;i<2;++i)   if ((j=tree[rt].ch[i])) add(j,x,y);
tree[rt].mint=-1;
}
int rebuild(int l=1,int r=m,bool d=0,int f=0)
{
cmp_d=d;int mid=(l+r)>>1;nth_element(tree+l,tree+mid,tree+r+1);
id[tree[mid].f]=mid;tree[mid].f=f;tree[mid].init();
if (l!=mid) tree[mid].ch[0]=rebuild(l,mid-1,d^1,mid);
if (r!=mid) tree[mid].ch[1]=rebuild(mid+1,r,d^1,mid);
return push_up(mid),mid;
}
inline int check(int x1,int y1,int x2,int y2,int x,int y)
{
int ret=0;
ret+=(x1<=x&&y1>=y);ret+=(x1<=x&&y2>=y);ret+=(x2<=x&&y1>=y);ret+=(x2<=x&&y2>=y);
return ret?(ret==4?1:2):0;
}
void modify(int rt,int x,int y,int id)
{
int flag=check(tree[rt].minn[0],tree[rt].minn[1],tree[rt].maxn[0],tree[rt].maxn[1],x,y);
if (flag==1)    return;
if (tree[rt].d[0]>x||tree[rt].d[1]<y)   tree[rt].maxv[1]=max(tree[rt].maxv[1],id-tree[rt].maxt[1]-1),tree[rt].maxt[1]=id;
push_down(rt);
for (int i=0;i<2;++i)   if (tree[rt].ch[i]) modify(tree[rt].ch[i],x,y,id);
}
void update(int rt,int x)
{
push_down(rt);
tree[rt].maxv[1]=max(tree[rt].maxv[1],n-tree[rt].maxt[1]);
tree[rt].maxv[1]=max(tree[rt].maxv[1],x);
tree[rt].maxv[0]=max(tree[rt].maxv[0],x);
tree[rt].maxv[1]=max(tree[rt].maxv[1],tree[rt].maxv[0]);
for (int i=0;i<2;++i)   if (tree[rt].ch[i]) update(tree[rt].ch[i],tree[rt].maxv[0]);
}
int main()
{
in(n);in(m);
for (int i=1;i<=n;++i)  in(y[i]),in(x[i]);
for (int i=1;i<=m;++i)  in(tree[i].d[0]),in(tree[i].d[1]),tree[i].f=i;
root=rebuild();
for (int i=1;i<=n;++i)  modify(root,x[i],y[i],i);
update(root,0);
for (int i=1;i<=m;++i)  printf("%d\n",tree[id[i]].maxv[1]);
}