#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])]);
    }
  }
}