#include<bits/stdc++.h>
using namespace std;
#define Max 100005
int child[Max][2],fa[Max],size[Max],lazy[Max];
int n,m,root;
void updet(int x) //更新以x为根节点树的位置;
{
size[x] = size[child[x][0]] + size[child[x][1]] + 1;
}
void pushdown(int x) // 向下传懒惰标记;
{
if(lazy[x])
{
lazy[x] ^= 1;
lazy[child[x][0]] ^= 1;
lazy[child[x][1]] ^= 1;
swap(child[x][0],child[x][1]);
}
}
int build(int left ,int right ,int f) // 建树;
{
int mid = (left+right)>>1;
fa[mid] = f;
if(left < mid) child[mid][0] = build(left, mid-1, mid);
if(right > mid) child[mid][1] = build(mid+1, right, mid);
updet(mid);
return mid;
}
int find(int x, int k) // 查找
{
pushdown(x); // 一定要注意 pushdown 的位置;
while(k!=size[child[x][0]]+1)
{
if(k>size[child[x][0]]+1)
{
k -= size[child[x][0]]+1;
x = child[x][1];
}
else x = child[x][0];
pushdown(x);
}
return x;
}
void print(int x)
{
if(x==0) return ;
pushdown(x);
print(child[x][0]);
if(x!= 1) printf("%d\n",x - 1);
print(child[x][1]);
}
int get(int x,int f)
{
if(child[f][1]==x)
return 1;
return 0;
}
// 一定要注意重新与根节点连接的时,从根节点连孩子这条线(这个孩子有两种可能)
//(1) 可能是要移的那个点 (2)也可能是倒数第二步,这步中的x的父亲
// 因为当同向时,先移父亲 后移自己;
void rotate(int x,int goal) // 三个位置的断开点,父连子,子连父,需六个重新连接;
{
int y = fa[x];
int z = fa[y];
int tt = get(x,y);
child[y][tt] = child[x][!tt];
fa[child[y][tt]] = y;
child[x][!tt] = y;
if(z!=goal) child[z][get(y,z)] = x;
// 一定要注意这个连接,让我找了两天啊
// 也就是splay(x,goal) 把x移动到目标位置的最后一步;不要让 目标位置的父亲连接 x;
// 因为在spile()分离函数中,已经把移到根节点的节点 的右儿子赋为0了
// 这个的话 get(y,z) 返回值一定是0;
// 就这个程序而言,最后一步不要让 目标位置的父亲连接 x;
// 但是若是 任意往上旋转的话,一定要注意这个连接,最后一步到底该不该要;
// 也就是一定要记得 除旋转操作函数中,一定要注意其他位置那个位置的连接改变;
// 这个连接(有父连子,子连父 两种操作);
fa[x] = z;
fa[y] = x;
updet(y),updet(x); // 也要注意 updet的位置;
}
void splay(int x,int t)
{
while(fa[x]!=t)
{
int y = fa[x], z = fa[y];
if(z == t)
rotate(x,t);
else if(get(x,y) == get(y,z)) // 同向,先旋转父亲,再旋转儿子
rotate(y,t),rotate(x,t);
else // 异向,旋转儿子,旋转儿子;
rotate(x,t),rotate(x,t);
}
}
void spile(int &x, int k, int &left, int &right)
{
int t1 = find(x, k);
splay(t1,fa[x]);
left = t1;
right = child[t1][1];
child[t1][1] = 0; //这里分离时把刚移到根节点的节点的右儿子赋予0了;
//在旋转操作中一定要记得;拆断重新连接时,一定要记得;
updet(t1);
x = t1;
}
int merge(int x,int y)
{
int t1 = find(x,size[x]);
splay(t1,fa[x]);
child[t1][1] = y;
fa[y] = t1;
updet(t1);
return t1;
}
// 若直接区间内的数反转的话,就不用,树的分裂 合并了,当时把,当前区间反转后,放到最后面
// 就改变了树的(较)平衡结构,所以要先分裂 分裂 再合并,再合并;
int main()
{
scanf("%d%d",&n,&m);
root = build(1,n+1,0);
while(m--)
{
int x, y, left, mid, right,nextroot;
scanf("%d%d", &x, &y);
spile(root,x,left,nextroot);
spile(nextroot,y-x+1,mid,right);
lazy[mid] ^= 1;
root = merge(merge(left,right),mid);
}
print(root);
return 0;
}