#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
const int N=1e5+5;
int tree[N<<2],mark[N<<2],A[N],n,m,val[N],q;
struct ask
{
int l,r,t;
}que[N];
void build(int p=1,int cl=1,int cr=n)
{
mark[p]=-1;
if(cl==cr) return void(tree[p]=A[cl]);
int mid=(cl+cr)>>1;
build(p<<1,cl,mid);
build(p<<1|1,mid+1,cr);
tree[p]=tree[p<<1]+tree[p<<1|1];
}
void push_down(int p,int len)
{
if(len<=1 || mark[p]<0) return;
tree[p<<1]=mark[p]*(len-len/2);
tree[p<<1|1]=mark[p]*(len/2);
mark[p<<1]=mark[p];
mark[p<<1|1]=mark[p];
mark[p]=-1;
}
void update(int l,int r,int d,int p=1,int cl=1,int cr=n)
{
if(cl>=l && cr<=r)
{
tree[p]=d*(cr-cl+1);
mark[p]=d; return;
}
push_down(p,cr-cl+1);
int mid=(cl+cr)>>1;
if(mid>=l) update(l, r, d, p<<1, cl, mid);
if(r>=mid+1) update(l, r, d, p<<1|1, mid+1, cr);
tree[p]=tree[p<<1]+tree[p<<1|1];
}
int query(int l,int r,int p=1,int cl=1,int cr=n)
{
if(cl>=l && cr<=r) return tree[p];
push_down(p,cr-cl+1);
int mid=(cl+cr)>>1; int res=0;
if(mid>=l) res+=query(l, r, p<<1, cl, mid);
if(r>=mid+1) res+=query(l ,r, p<<1|1, mid+1, cr);
return res;
}
bool check(int mid)
{
int n1;
for(int i=1;i<=n;++i)
{
if(val[i]>=mid) A[i]=1;
else A[i]=0;
}
build();
for(int i=1;i<=m;++i)
{
n1=query(que[i].l,que[i].r);
if(n1==0) continue;
if(que[i].t==0)
{
update(que[i].r-n1+1, que[i].r, 1);
update(que[i].l, que[i].r-n1, 0);
}
else
{
update(que[i].l,que[i].l+n1-1,1);
update(que[i].l+n1, que[i].r, 0);
}
}
return query(q,q)==1;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;++i) cin>>val[i];
for(int i=1;i<=m;++i) cin>>que[i].t>>que[i].l>>que[i].r;
cin>>q;
int l=1,r=n,res;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))
{
res=mid;
l=mid+1;
}
else r=mid-1;
}
cout<<res;
}