#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
return x*f;
}
const int inf=0x3f3f3f3f;
struct node{
int d[2];
int& operator [](int x){return d[x];}
}P;
const int N=55000;
int root,D,n,Q,x1,y1,x2,y2,q[N],top,num,cnt,rt[N*30];
struct node1{
node x;int mn[2],mx[2],left,right,size;
}tree[N*30];
struct node2{
int left,right;
}tr[N*30];
inline void update(int x){
int l=tree[x].left,r=tree[x].right;
for (int i=0;i<2;++i) tree[x].mn[i]=min(tree[x].x[i],min(tree[l].mn[i],tree[r].mn[i]));
for (int i=0;i<2;++i) tree[x].mx[i]=max(tree[x].x[i],max(tree[l].mx[i],tree[r].mx[i]));
tree[x].size=tree[l].size+tree[r].size+1;
}
inline void dfs(int x){
if(!x) return;q[++top]=x;
dfs(tree[x].left);dfs(tree[x].right);
}
inline bool cmp(const int &a,const int &b){
return tree[a].x[D]<tree[b].x[D];
}
inline void build(int &x,int l,int r,int d){
int mid=l+r>>1;D=d;nth_element(q+l,q+mid,q+r+1,cmp);x=q[mid];
for (int i=0;i<2;++i) tree[x].mn[i]=tree[x].mx[i]=tree[x].x[i];
tree[x].left=tree[x].right=0;tree[x].size=1;
if (l<mid) build(tree[x].left,l,mid-1,d^1);
if (r>mid) build(tree[x].right,mid+1,r,d^1);update(x);
}
inline void rebuild(int &x,int d){
top=0;dfs(x);build(x,1,top,d);
}
inline void insert1(int &x,int d,bool flag){
if (!x) {x=++cnt;tree[x].x=P;update(x);return;}
int l=tree[x].left,r=tree[x].right;bool tag=0;
if (P[d]<tree[x].x[d]) {
if ((tree[l].size+1)*4>(tree[x].size+1)*3) insert1(tree[x].left,d^1,1),tag=1;
else insert1(tree[x].left,d^1,flag);
}else{
if ((tree[r].size+1)*4>(tree[x].size+1)*3) insert1(tree[x].right,d^1,1),tag=1;
else insert1(tree[x].right,d^1,flag);
}update(x);
if (tag&&!flag) rebuild(x,d);
}
inline int query(int x){
if (!x) return 0;
if (x1<=tree[x].mn[0]&&y1<=tree[x].mn[1]&&x2>=tree[x].mx[0]&&y2>=tree[x].mx[1]) return tree[x].size;
if (tree[x].mx[0]<x1||tree[x].mx[1]<y1||tree[x].mn[0]>x2||tree[x].mn[1]>y2) return 0;
int tmp=(tree[x].x[0]<=x2&&tree[x].x[0]>=x1&&tree[x].x[1]<=y2&&tree[x].x[1]>=y1);
tmp+=query(tree[x].left)+query(tree[x].right);return tmp;
}
inline void ins(int &x,int l,int r,int p){
if (!x) x=++num;insert1(rt[x],0,0);
if (l==r) return;int mid=l+r>>1;
if (p<=mid) ins(tr[x].left,l,mid,p);
else ins(tr[x].right,mid+1,r,p);
}
inline int qr(int x,int l,int r,int k){
if (l==r) return l;int mid=l+r>>1;
int tmp=query(rt[tr[x].right]);
if(k<=tmp) return qr(tr[x].right,mid+1,r,k);
else return qr(tr[x].left,l,mid,k-tmp);
}
int main(){
freopen("bzoj4604.in","r",stdin);
n=read();Q=read();tree[0].mn[0]=tree[0].mn[1]=inf;
tree[0].mx[0]=tree[0].mx[1]=0;
while(Q--){
int op=read();
if (op==1){
int x=read(),y=read(),v=read();
P[0]=x;P[1]=y;ins(root,1,1000000000,v);
}else{
x1=read(),y1=read(),x2=read(),y2=read();int k=read();
if (query(rt[1])<k) {puts("NAIVE!ORZzyz.");continue;}
printf("%d\n",qr(root,1,1000000000,k));
}
}
return 0;
}