#include<iostream>
#include<climits>
#include<cstdio>
#include<cstring>
#define rep(i,j,k) for(register int i(j);i<=k;++i)
#define drp(i,j,k) for(register int i(j);i>=k;--i)
#define bug puts("~~~~~~");
#define bugout(x) cout<<x<<endl;
using namespace std;
typedef long long lxl;
template<typename T>
inline T max(T &a, T &b) {
return a > b ? a : b;
}
template<typename T>
inline T min(T &a, T &b) {
return a < b ? a : b;
}
inline char gt() {
static char buf[1 << 21], *p1 = buf, *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename T>
inline void read(T &x) {
register char ch = gt();
x = 0;
int w(0);
while(!(ch >= '0' && ch <= '9'))w |= ch == '-', ch = gt();
while(ch >= '0' && ch <= '9')x = x * 10 + (ch & 15), ch = gt();
w ? x = ~(x - 1) : x;
}
template <typename T>
inline void out(T x) {
if(x < 0) x = -x, putchar('-');
char ch[20];
int num(0);
while(x || !num) ch[++num] = x % 10 + '0', x /= 10;
while(num) putchar(ch[num--]);
putchar('\n');
}
const int N = 1e5 + 79;
int n, m, q;
int a[N];
struct opt {
int op, l, r;
} p[N];
struct SegmentTree {
int lc[N << 1], rc[N << 1], root, cnt;
int lazy[N << 1], data[N << 1];
inline void init() {
cnt = 0;
root = 0;
memset(lc, 0, sizeof lc);
memset(lazy, 0xff, sizeof lazy);
memset(rc, 0, sizeof rc);
memset(data, 0, sizeof data);
}
inline void pushdown(int p, int L, int R) {
if(lazy[p] == -1) return ;
int mid(L + R >> 1);
lazy[rc[p]] = lazy[lc[p]] = lazy[p];
if(lazy[p]) {
data[lc[p]] = mid - L + 1;
data[rc[p]] = R - mid;
} else data[lc[p]] = data[rc[p]] = 0;
lazy[p] = 0;
}
inline void insert(int &p, int L, int R, int pos, int val) {
if(!p) p = ++cnt;
if(L == R) {
data[p] = val;
return ;
}
int mid(L + R >> 1);
if(pos <= mid) insert(lc[p], L, mid, pos, val);
else insert(rc[p], mid + 1, R, pos, val);
data[p] = data[lc[p]] + data[rc[p]];
}
inline void change(int p, int L, int R, int ll, int rr, int val) {
if(!p) return;
if(ll <= L && rr >= R) {
data[p] = val * (R - L + 1);
lazy[p] = val;
return ;
}
pushdown(p, L, R);
int mid(L + R >> 1);
if(ll <= mid) change(lc[p], L, mid, ll, rr, val);
if(rr > mid) change(rc[p], mid + 1, R, ll, rr, val);
data[p] = data[lc[p]] + data[rc[p]];
}
inline int query(int p, int L, int R, int ll, int rr) {
if(!p) return 0;
if(ll <= L && rr >= R) {
return data[p];
}
pushdown(p, L, R);
int mid(L + R >> 1), ans(0);
if(ll <= mid) ans += query(lc[p], L, mid, ll, rr) ;
if(rr > mid) ans += query(rc[p], mid + 1, R, ll, rr);
return ans;
}
} S;
inline int check(int x) {
S.init();
rep(i, 1, n) {
S.insert(S.root, 1, n, i, a[i] >= x);
}
rep(i, 1, m) {
int cnt = S.query(S.root, 1, n, p[i].l, p[i].r);
if(p[i].op == 0) {
S.change(S.root, 1, n, p[i].r - cnt + 1, p[i].r, 1);
S.change(S.root, 1, n, p[i].l, p[i].r - cnt , 0);
} else {
S.change(S.root, 1, n, p[i].l + cnt, p[i].r, 0);
S.change(S.root, 1, n, p[i].l, p[i].l + cnt - 1, 1);
}
}
return S.query(S.root, 1, n, q, q);
}
int main() {
read(n);
read(m);
rep(i, 1, n) {
read(a[i]);
}
rep(i, 1, m) {
read(p[i].op);
read(p[i].l);
read(p[i].r);
}
read(q);
int l = 1, r = n, mid, ans;
while(l <= r) {
mid = (l + r) >> 1;
if(check(mid)) {
l=mid+1;
ans=mid;
}
else r=mid-1;
}
out(ans);
return 0;
}