#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<set>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<iostream>
#include<string>
#include<cmath>
#define lc(x) (x<<1)
#define rc(X) ((x<<1)+1)
#define N 4010000
#define M 1010000
#define FOR(i,a,b) for(i=(a);i<=(b);i++)
#define ROF(i,a,b) for(i=(a);i>=(b);i--)
typedef long long LL;
using namespace std;
int root[M],ml[M],mr[M],mlc[M],mrc[M],mlen=1,t[M],L,n,m;
int l[N],r[N],lc[N],rc[N],lazy[N],len=1,sum[N];bool flag[N];
int op[M],x[M],y[M],c[M];
void equal(int x,int y)
{l[x]=l[y];r[x]=r[y];lc[x]=lc[y];rc[x]=rc[y];sum[x]=sum[y];lazy[x]=lazy[y];}
void mbuild(int x,int L,int R)
{
ml[x]=L;mr[x]=R;int mid=(L+R)>>1;
if (L==R) return;
mlc[x]=++mlen;mbuild(mlc[x],L,mid);
mrc[x]=++mlen;mbuild(mrc[x],mid+1,R);
}
void build(int x,int L,int R)
{
l[x]=L;r[x]=R;sum[x]=0;flag[x]=1;
if (L==R) return;
int mid=(L+R)>>1;
lc[x]=++len;build(lc[x],L,mid);
rc[x]=++len;build(rc[x],mid+1,R);
}
void pushdown(int x)
{
sum[lc[x]]+=lazy[x]*(r[lc[x]]-l[lc[x]]+1);lazy[lc[x]]+=lazy[x];
sum[rc[x]]+=lazy[x]*(r[rc[x]]-l[rc[x]]+1);lazy[rc[x]]+=lazy[x];
lazy[x]=0;
}
void newl(int x)
{if (flag[lc[x]]) {int t=lc[x];lc[x]=++len;equal(lc[x],t);}}
void newr(int x)
{if (flag[rc[x]]) {int t=rc[x];rc[x]=++len;equal(rc[x],t);}}
void modify(int x,int L,int R)
{
if (l[x]==L&&r[x]==R)
{
lazy[x]+=1;
sum[x]+=r[x]-l[x]+1;
return;
}
int mid=(l[x]+r[x])>>1;
if (R<=mid) {newl(x);modify(lc[x],L,R);}
else if (L>mid) {newr(x);modify(rc[x],L,R);}
else {newl(x);newr(x);modify(lc[x],L,mid);modify(rc[x],mid+1,R);}
sum[x]=lazy[x]*(r[x]-l[x]+1)+sum[lc[x]]+sum[rc[x]];
}
void mmodify(int x,int p,int L,int R)
{
modify(root[x],L,R);
if (ml[x]==mr[x]) return;
int mid=(ml[x]+mr[x])>>1;
if (p<=mid) mmodify(mlc[x],p,L,R);
else mmodify(mrc[x],p,L,R);
}
int query(int x,int L,int R)
{
if (l[x]==L&&r[x]==R) return sum[x];
int mid=(l[x]+r[x])>>1,res;
if (R<=mid) res=query(lc[x],L,R);
else if (L>mid) res=query(rc[x],L,R);
else res=query(lc[x],L,mid)+query(rc[x],mid+1,R);
return res+lazy[x]*(min(R,r[x])-max(L,l[x])+1);
}
int mquery(int x,int kth,int L,int R)
{
if (ml[x]==mr[x]) return ml[x];
int tmp=query(root[mrc[x]],L,R);
if (kth>tmp) return mquery(mlc[x],kth-tmp,L,R);
else return mquery(mrc[x],kth,L,R);
}
int get(int x)
{
int *p=lower_bound(t+1,t+L,x);
return p-t;
}
int main()
{
scanf("%d%d",&n,&m);
len=1;int i;L=0;
FOR(i,1,m)
{
scanf("%d%d%d%d",&op[i],&x[i],&y[i],&c[i]);
if (op[i]==1) t[++L]=c[i];
}
sort(t+1,t+1+L);
L=unique(t+1,t+1+L)-t-1;
mbuild(1,1,L);
build(1,1,n);
FOR(i,len+1,len+mlen) {root[i-len]=i;equal(i,1);}
len+=mlen;
FOR(i,1,m)
{
if (op[i]==1)
{
mmodify(1,get(c[i]),x[i],y[i]);
}else
{
printf("%d\n",t[mquery(1,c[i],x[i],y[i])]);
}
}
}