#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5;
int n,m;
int tree[N<<2],lazy[N<<2],flag[N<<2];
struct node{
int f,l,r,id,ans,val,next;
}a[N];
inline bool cmp1(node x,node y){
return x.next>y.next;
}
inline bool cmp2(node x,node y){
return x.id>y.id;
}
inline void memset(int node){
int w=node<<1,e=node<<1|1;
tree[w]=tree[e]=lazy[w]=lazy[e]=flag[node]=0;
flag[w]=flag[e]=1;
}
inline void pushdown(int node,int l,int r){
int mid=l+(r-l>>1),w=node<<1,e=node<<1|1;
tree[w]+=(mid-l+1)*lazy[node];
tree[e]+=(r-mid)*lazy[node];
lazy[w]+=lazy[node];
lazy[e]+=lazy[node];
lazy[node]=0;
}
inline void update(int node,int l,int r,int x,int y){
if(flag[node])
memset(node);
if(x<=l&&r<=y){
tree[node]+=r-l+1;
lazy[node]++;
return;
}
if(lazy[node])
pushdown(node,l,r);
int mid=l+(r-l>>1),w=node<<1,e=node<<1|1;
if(x<=mid)
update(w,l,mid,x,y);
if(y>mid)
update(e,mid+1,r,x,y);
tree[node]=tree[w]+tree[e];
}
inline int query(int node,int l,int r,int x,int y){
if(flag[node])
memset(node);
if(x<=l&&r<=y)
return tree[node];
if(lazy[node])
pushdown(node,l,r);
int mid=l+(r-l>>1),ans=0,w=node<<1,e=node<<1|1;
if(x<=mid)
ans+=query(w,l,mid,x,y);
if(y>mid)
ans+=query(e,mid+1,r,x,y);
return ans;
}
inline void ztef(int l,int r,int x,int y){
if(l==r){
for(int i=x;i<=y;i++)
a[i].ans=l;
return;
}
flag[1]=1;
tree[1]=lazy[1]=0;
int xx=0,yy=y,mid=l+(r-l>>1);
for(int i=x;i<=y;i++)
if(a[i].f==1)
if(a[i].val<=mid){
xx++;
a[i].next=xx;
}
else{
yy++;
a[i].next=yy;
update(1,1,n,a[i].l,a[i].r);
}
else{
int w=query(1,1,n,a[i].l,a[i].r);
if(w<a[i].val){
a[i].val-=w;
xx++;
a[i].next=xx;
}
else{
y++;
a[i].next=yy;
}
}
sort(a+1,a+m+1,cmp1);
ztef(l,mid,x,x+xx-1);
ztef(mid+1,r,x+xx,y);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a[i].f>>a[i].l>>a[i].r>>a[i].val;
a[i].id=i;
}
ztef(-n,n,1,m);
sort(a+1,a+m+1,cmp2);
for(int i=1;i<=m;i++)
if(a[i].f==2)
cout<<a[i].ans<<endl;
return 0;
}