rt 用的是树状数组做的
#include <bits/stdc++.h>
#define YES return void(cout << "Yes\n")
#define NO return void(cout << "No\n")
using namespace std;
using u64 = unsigned long long;
using PII = pair<int, int>;
using i64 = long long;
template<typename T>
struct BIT {
const int n;
vector<T> tree;
BIT(int n) : n(n), tree(n + 1) {};
T qry(int x) {
T res = 0;
for (int i = x; i > 0; i -= (i & -i))
res += tree[i];
return res;
}
void upd(int l, T z) {
for (int i = l; i <= n; i += (i & -i))
tree[i] += z;
}
T qryseg(int l, int r) {
return qry(min(n, r)) - qry(max(0, l - 1));
}
};
void solve() {
int c, q;
cin >> c >> q;
BIT<i64> fen(2e5 + 10);
multiset<i64, greater<i64>> mx;
queue<pair<i64, i64>> que;
int op, l = 1, r = 0;
auto check = [&](int mid, i64 ask) {
return fen.qryseg(l, mid) < ask;
};
for (int i = 1; i <= q; ++i) {
cin >> op;
if (op == 1) {
i64 x; cin >> x;
que.emplace(1, x);
fen.upd(++r, x);
mx.insert(x);
}
else if (op == 2) {
i64 y; cin >> y;
while (y) {
auto& [S, T] = que.front();
i64 d = min(T - S + 1, y);
y -= d;
if (y == 0) {
S += d;
fen.upd(l, -d);
break;
} else {
mx.erase(mx.find(T));
que.pop(), ++l;
}
}
}
else if (op == 3) {
i64 z; cin >> z;
int L = l, R = r;
while (L < R) {
int mid = L + R + 1 >> 1;
if (check(mid, z)) L = mid;
else R = mid - 1;
}
if (L == l) {
i64 d = que.front().second - que.front().first + 1;
if (z > d) {
cout << z - d << '\n';
} else {
cout << z + que.front().first - 1 << '\n';
}
}
else {
z -= fen.qryseg(l, L);
cout << z << '\n';
}
}
else if (op == 4) {
cout << *mx.begin() << '\n';
}
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int t = 1; //cin >> t;
while (t--) solve();
return 0;
}