#include<bits/stdc++.h>
#define ll long long
#define mid (l+r>>1)
#define ls T[rt].l
#define rs T[rt].r
using namespace std;
const int N=4e5;
vector<int> num;
int root[N<<2];
int n,m,rp;
struct Q {
int op,l,r;
ll x;
}a[N];
struct SGT
{
int tot;
struct node {
int l,r,tag;
ll cnt;
}T[N<<7];
void push_down(int rt,int l,int r)
{
int tag=T[rt].tag; T[rt].tag=0;
if (!ls) ls=++tot; if (!rs) rs=++tot;
T[ls].tag+=tag,T[ls].cnt+=1ll*tag*(mid-l+1);
T[rs].tag+=tag,T[rs].cnt+=1ll*tag*(r-mid);
}
void modify(int &rt,int l,int r,int L,int R)
{
if (!rt) rt=++tot; if (L<=l&&r<=R) return
T[rt].tag++,T[rt].cnt+=r-l+1,void();
push_down(rt,l,r);
if (L<=mid) modify(ls,l,mid,L,R);
if (mid<R) modify(rs,mid+1,r,L,R);
T[rt].cnt=T[ls].cnt+T[rs].cnt;
}
ll query(int rt,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return T[rt].cnt;
push_down(rt,l,r);
if (R<=mid) return query(ls,l,mid,L,R);
if (mid<L) return query(rs,mid+1,r,L,R);
return query(ls,l,mid,L,R)+query(rs,mid+1,r,L,R);
}
}A;
void update(int rt,int l,int r,int L,int R,int p) {
A.modify(root[rt],1,n,L,R); if (l==r) return;
p<=mid?update(rt<<1,l,mid,L,R,p):update(rt<<1|1,mid+1,r,L,R,p);
}
int Query(int rt,int l,int r,int L,int R,ll k) {
if (l==r) return l; ll cnt=A.query(root[rt<<1|1],1,n,L,R);
return k>cnt?Query(rt<<1,l,mid,L,R,k-cnt):Query(rt<<1|1,mid+1,r,L,R,k);
}
int Hash(int x) {
return lower_bound(num.begin(),num.end(),x)-num.begin();
}
int main()
{
scanf("%d%d",&n,&m); for (int i=0;i<m;i++)
scanf("%d%d%d%lld",&a[i].op,&a[i].l,&a[i].r,&a[i].x);
for (int i=0;i<m;i++) if (a[i].op==1) num.push_back(a[i].x);
sort(num.begin(),num.end() ),num.erase(unique(num.begin(),num.end() ),num.end() );
for (int i=0;i<m;i++)
{
int op=a[i].op,l=a[i].l,r=a[i].r;
if (op==1) update(1,0,num.size()-1,l,r,Hash(a[i].x) );
else printf("%d\n",num[Query(1,0,num.size()-1,l,r,a[i].x)]);
}
return 0;
}