#include<iostream>
#include<algorithm>
const int sz = 5e4 + 10;
int n, q;
struct que {
int op, l, r, c;
} que[sz];
int arr[sz], carr[sz];
struct SegTree {
struct node {
int lson, rson, val, lazy;
} tree[sz << 9];
int num;
void pushdown(int p, int ln, int rn) {
if (tree[p].lazy) {
int mid = ln + rn >> 1;
if (tree[p].lson == 0) tree[p].lson = ++num;
if (tree[p].rson == 0) tree[p].rson = ++num;
tree[tree[p].lson].val += tree[p].lazy * (mid - ln + 1);
tree[tree[p].rson].val += tree[p].lazy * (rn - mid);
tree[tree[p].lson].lazy += tree[p].lazy;
tree[tree[p].rson].lazy += tree[p].lazy;
tree[p].lazy = 0;
}
}
void add(int &p, int ln, int rn, int l, int r, int val) {
if (p == 0) p = ++num;
if (ln >= l && rn <= r)
return tree[p].val += (rn - ln + 1) * val, tree[p].lazy += val, void();
int mid = ln + rn >> 1;
pushdown(p, ln, rn);
if (l <= mid) add(tree[p].lson, ln, mid, l, r, val);
if (r > mid) add(tree[p].rson, mid + 1, rn, l, r, val);
tree[p].val = tree[tree[p].lson].val + tree[tree[p].rson].val;
}
int query(int p, int ln, int rn, int l, int r) {
if (p == 0) return 0;
if (ln >= l && rn <= r) return tree[p].val;
int mid = ln + rn >> 1, res = 0;
pushdown(p, ln, rn);
if (l <= mid) res += query(tree[p].lson, ln, mid, l, r);
if (r > mid) res += query(tree[p].rson, mid + 1, rn, l, r);
return res;
}
} segt;
struct ST {
int root[sz << 2];
void add(int p, int ln, int rn, int pos, int l, int r, int val) {
segt.add(root[p], 1, n, l, r, val);
if (ln == rn) return;
int mid = ln + rn >> 1;
if (pos <= mid) add(p << 1, ln, mid, pos, l, r, val);
else add(p << 1 | 1, mid + 1, rn, pos, l, r, val);
}
int query(int p, int ln, int rn, int l, int r, int k) {
if (ln == rn) return ln;
int mid = ln + rn >> 1;
int gsz = segt.query(root[p << 1 | 1], 1, n, l, r);
if (k > gsz) return query(p << 1, ln, mid, l, r, k - gsz);
else return query(p << 1 | 1, mid + 1, rn, l, r, k);
}
} st;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> q;
int xpp = 0;
for (int i = 1; i <= q; i++) {
std::cin >> que[i].op >> que[i].l >> que[i].r >> que[i].c;
if (que[i].op == 1) arr[++xpp] = que[i].c;
}
std::copy(arr + 1, arr + xpp + 1, carr + 1);
std::sort(carr + 1, carr + xpp + 1);
int f = std::unique(carr + 1, carr + xpp + 1) - carr;
for (int i = 1; i <= q; i++) {
int op = que[i].op, l = que[i].l, r = que[i].r, c = que[i].c;
if (op == 1) c = std::lower_bound(carr + 1, carr + f, c) - carr, st.add(1, 1, f - 1, c, l, r, 1);
else std::cout << carr[st.query(1, 1, f - 1, l, r, c)] << "\n";
}
return 0;
}