/**
POJ 3667 Hotel 模拟+暴力
链接:http://poj.org/problem?id=3667
题意:给定长度为n初始化值为0的数组a,每次询问存在两个操作;
1 x : 新添进来值为1,大小长度为x的数组b.每次新添进去的位置为:最左边,且能全部一次性放下的地点
也就是最左边连续0的个数的长度得大于等于x,输出当前赋值的起始点;
2 x d: 以x为起点长度为d的后面位置全部清为0;
分析:可用vector进行模拟,存取节点,节点表示1-->n值为0的区间,维护一个单调的vector;
对于询问操作,直接暴力vec进行遍历即可,并注意当前满足条件的区间变化;
对于区间推平操作,找到最右边的点的位置,对于左端点到当前最右的点,进行删除,即可完成区间推平操作
也就是将多个不为0的区间化为一个区间的过程;
*/
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
int n,q;
struct node {
int l,r;
};
vector<node>vec;
int main(){
scanf("%d %d",&n,&q);
node tmp;tmp.l=1,tmp.r=n;
vec.push_back(tmp);
while(q--){
int cas;scanf("%d",&cas);
if(cas==1) {
int x;scanf("%d",&x);
int id=0,sz=vec.size();//至少存在一个,留;
//for(int i=0;i<sz-1;i++) if((vec[i].r-vec[i].l+1)>=x) { id=i;break;}
while((vec[id].r-vec[id].l+1)<x&&id<vec.size()-1) id++;//保证vec不能为空 方便下面的判断;
if((vec[id].r-vec[id].l+1)>=x){
printf("%d\n",vec[id].l);
vec[id].l+=x;
if(vec[id].l>vec[id].r) vec.erase(vec.begin()+id);
}
else puts("0");
}
else {
int x,d;scanf("%d %d",&x,&d);
d=x+d-1;
node tmp;tmp.l=x,tmp.r=d;
if(vec.size()==0) vec.push_back(tmp);//全是满的情况;
else if(vec.size()==1){
if(vec[0].l-1>d) vec.insert(vec.begin(),1,tmp);//记得维护vec的区间单调性(递增);
else if(vec[0].r<x-1) vec.push_back(tmp);
else vec[0].l=min(vec[0].l,x),vec[0].r=max(vec[0].r,d);
}
else if(vec.size()>1){
int id=0,sz=vec.size();
//for(int i=0;i<sz-1;i++) if(vec[i].r+1>=x) { id=i; break; }
while((vec[id].r+1)<x&&id<vec.size()-1) id++;
if(vec[id].l-1>d) vec.insert(vec.begin()+id,1,tmp);
else if(vec[id].r<x-1) vec.push_back(tmp);
else {
vec[id].l=min(vec[id].l,x),vec[id].r=max(vec[id].r,d);
for(int i=id;i<vec.size()-1;){
if(vec[i+1].l-1>vec[i].r) break;
vec[i].r=max(vec[i].r,vec[i+1].r);
vec.erase(vec.begin()+i+1);
}
}
}
}
}
return 0;
}
/**
10 6
1 4
1 4
2 2 5
*/