很难受
#include<cstdio>
#include<cstring>
const int N=200007;
int read()
{
int ans=0;char t=getchar();
while(t<'0'||t>'9') t=getchar();
while(t>='0'&&t<='9') ans=ans*10+t-'0',t=getchar();
return ans;
}
int L[N],R[N];
int qu[N],f[N];
inline int max(int a,int b)
{
return a>b?a:b;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
int n=read(),p=read();
for(int i=1;i<=n+1;i++) R[i]=i-1;//转移方程中j<i
int l,r;
for(int i=1;i<=p;i++)
{
l=read(),r=read();
R[r]=min(R[r],l-1);
L[r+1]=max(L[r+1],l);
}
for(int i=n;i>=1;i--) R[i]=min(R[i+1],R[i]);
for(int i=2;i<=n+1;i++) L[i]=max(L[i-1],L[i]);
int head=1,tail=1,j=1;qu[1]=0;
for(int i=1;i<=n+1;i++)
{
while(j<=R[i]&&j<=n)
{
if(f[j]==-1||j<L[i]) j++;
else
{
while(head<=tail&&f[j]>f[qu[tail]]) tail--;
qu[++tail]=j;
j++;
}
}
while(qu[head]<L[i]&&head<=tail) head++;
if(head<=tail) f[i]=f[qu[head]]+(i!=n+1?1:0);
else f[i]=-1;
}
// for(int i=1;i<=n+1;i++) printf("%d ",f[i]);
printf("%d\n",f[n+1]);
return 0;
}