#include <bits/stdc++.h>
#define int long long
#define up(i ,x ,y) for (int i = x ; i <= y ; i ++)
using namespace std;
const int N = 2e5 + 10;
int ls[N << 5] ,rs[N << 5] ,sum[N << 5];
int tp ,idx ,rubbish[N << 5];
int n ,m ,a[N] ,rt[N];
inline void pushup (int u){
sum[u] = sum[ls[u]] + sum[rs[u]];
} inline void del (int u){
ls[u] = rs[u] = sum[u] = 0;
rubbish[++ tp] = u;
} inline int newnode (){
return tp ? rubbish[tp --] : ++ idx;
} inline void insert (int &u ,int l ,int r ,int x ,int v){
if (!u) u = newnode ();
sum[u] += v ;
if (l == r) return;
int mid = ((l + r) >> 1);
if (x <= mid) insert (ls[u] ,l ,mid ,x ,v);
else insert (rs[u] ,mid + 1 ,r ,x ,v);
} inline int merge (int x ,int y ,int l ,int r){
if (!x || !y) return x | y;
sum[x] += sum[y];
if (l == r) return x;
int mid = ((l + r) >> 1);
ls[x] = merge (ls[x] ,ls[y] ,l ,mid);
rs[x] = merge (rs[x] ,rs[y] ,mid + 1 ,r);
del (y);
return x;
} inline void split (int x ,int &y ,int k){
if (!x) return ;
y = newnode ();
int sz = sum[ls[x]];
if (sz < k) split (rs[x] ,rs[y] ,k - sz);
else if (sz == k) {rs[y] = rs[x] ,rs[x] = 0 ;}
else rs[y] = rs[x] ,rs[x] = 0 ,split (ls[x] ,ls[y] ,k);
pushup (y) ; pushup (x);
} inline int query_range (int u ,int l ,int r ,int ql ,int qr){
if (l >= ql && r <= qr) return sum[u];
int mid = ((l + r) >> 1) ,res = 0;
if (ql <= mid) res += query_range (ls[u] ,l ,mid ,ql ,qr);
if (mid < qr) res += query_range (rs[u] ,mid + 1 ,r ,ql ,qr);
return res;
} inline int query_num (int u ,int l ,int r ,int k){
if (l == r) return l;
int sz = sum[ls[u]] ,mid = ((l + r) >> 1);
if (sz < k) return query_num (rs[u] ,mid + 1 ,r ,k - sz);
return query_num (ls[u] ,l ,mid ,k);
} signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m;
up (i ,1 ,n) cin >> a[i] ,insert (rt[1] ,1 ,n ,i ,a[i]);
int cnt = 1;
while (m --) {
int op ,p ,x ,y ,t ,q ,k;
cin >> op >> p;
if (op == 0) {
cin >> x >> y;
++ cnt;
int rt1 ,range1 = query_range (1 ,1 ,n ,1 ,x - 1) ,range2 = query_range (1 ,1 ,n ,x, y);
split (rt[p] ,rt[cnt] ,range1);
split (rt[cnt] ,rt1 ,range2);
rt[p] = merge (rt[p] ,rt1 ,1 ,n);
} if (op == 1) {
cin >> t;
merge (rt[p] ,rt[t] ,1 ,n);
} if (op == 2) {
cin >> x >> q;
insert (rt[p] ,1 ,n ,q ,x);
} if (op == 3) {
cin >> x >> y;
cout << query_range (rt[p] ,1 ,n ,x ,y) << endl;
} if (op == 4) {
cin >> k;
if (sum[rt[p]] < k) puts ("-1");
else cout << query_num (rt[p] ,1 ,n ,k) << endl;
}
}
return 0;
}
```