#include <bits/stdc++.h>
using i64 = long long;
#ifdef DEBUG
#include "debug.h"
#else
#define debug(...) void(23)
#endif
template<typename T>
bool chmax(T& a, T b) {
if (a < b) {
a = b;
return true;
}
return false;
}
constexpr int inf = int(1E9) + 5;
#ifdef LOCAL
std::mt19937 rng(23);
#else
std::random_device rd;
std::mt19937 rng(rd());
#endif
struct node {
int wei = rng();
int siz = 0;
int x = -1;
int y = -1;
int mny = inf;
int mxy = 0;
int lzx = -1;
int lzy = -1;
int lc = 0;
int rc = 0;
int par = 0;
node() {}
node(int x_, int y_) {
x = x_;
y = y_;
siz = 1;
mny = y_;
mxy = y_;
}
};
std::vector<node> tree = {{}};
int new_node(node nd = node()) {
tree.emplace_back(nd);
return int(tree.size()) - 1;
}
int new_node(int X, int Y) {
return new_node(node(X, Y));
}
void modify(int v, int x, int y) {
if (!v) {
return;
}
chmax(tree[v].x, x);
chmax(tree[v].lzx, x);
chmax(tree[v].y, y);
chmax(tree[v].lzy, y);
chmax(tree[v].mny, y);
chmax(tree[v].mxy, y);
}
void push(int v) {
if (!v) {
return;
}
modify(tree[v].lc, tree[v].lzx, tree[v].lzy);
modify(tree[v].rc, tree[v].lzx, tree[v].lzy);
tree[v].lzx = tree[v].lzy = -1;
}
void pull(int v) {
if (!v) {
return;
}
tree[v].siz = tree[tree[v].lc].siz + tree[tree[v].rc].siz + 1;
tree[v].mny = std::min({tree[v].y, tree[tree[v].lc].mny, tree[tree[v].rc].mny});
tree[v].mxy = std::max({tree[v].y, tree[tree[v].lc].mxy, tree[tree[v].rc].mxy});
tree[tree[v].lc].par = v;
tree[tree[v].rc].par = v;
if (tree[v].lc) {
assert(std::max(tree[v].lzx, tree[tree[v].lc].x) <= tree[v].x);
}
if (tree[v].rc) {
assert(std::max(tree[v].lzx, tree[tree[v].rc].x) >= tree[v].x);
}
}
void debug_node(int v, int lzx = 0, int lzy = 0, std::string ps = "") {
if (!v) {
return;
}
lzx = std::max(lzx, tree[v].lzx);
lzy = std::max(lzy, tree[v].lzy);
debug_node(tree[v].lc, lzx, lzy, ps + ":: ");
std::cerr << ps << std::max(lzx, tree[v].x) << ' ' << std::max(lzy, tree[v].y) << '\n';
debug_node(tree[v].rc, lzx, lzy, ps + ":: ");
}
void merge(int& v, int lv, int rv) {
if (!lv || !rv) {
v = (lv ? lv : rv);
return;
}
push(lv), push(rv);
if (tree[lv].wei > tree[rv].wei) {
merge(tree[lv].rc, tree[lv].rc, rv);
v = lv;
} else {
merge(tree[rv].lc, lv, tree[rv].lc);
v = rv;
}
// debug(__LINE__);
pull(v);
// debug(__LINE__);
}
// x[i]<=k
void split_by_x(int v, int& lv, int& rv, int k) {
if (!v) {
lv = rv = 0;
return;
}
push(v);
if (tree[v].x <= k) {
split_by_x(tree[v].rc, tree[v].rc, rv, k);
lv = v;
} else {
split_by_x(tree[v].lc, lv, tree[v].lc, k);
rv = v;
}
// debug(__LINE__);
pull(lv), pull(rv);
// debug(__LINE__);
}
void super_merge(int& v, int x, int y) {
if (!x || !y) {
v = (x ? x : y);
return;
}
push(x), push(y);
if (tree[x].wei < tree[y].wei) {
std::swap(x, y);
}
int ly, ry;
split_by_x(y, ly, ry, tree[x].x);
super_merge(tree[x].lc, tree[x].lc, ly);
super_merge(tree[x].rc, tree[x].rc, ry);
v = x;
// debug(__LINE__);
pull(v);
// debug(__LINE__);
}
// y[i]<=k
void split_by_y(int v, int& lv, int& rv, int k) {
if (!v) {
lv = rv = 0;
return;
}
if (tree[v].mny > k) {
lv = 0;
rv = v;
return;
}
if (tree[v].mxy <= k) {
lv = v;
rv = 0;
return;
}
push(v);
int lx, rx;
split_by_y(tree[v].lc, lx, rx, k);
int ly, ry;
split_by_y(tree[v].rc, ly, ry, k);
if (tree[v].y <= k) {
tree[v].lc = lx;
tree[v].rc = ly;
int w;
merge(w, rx, ry);
lv = v;
rv = w;
} else {
tree[v].lc = rx;
tree[v].rc = ry;
int w;
merge(w, lx, ly);
lv = w;
rv = v;
}
// debug(__LINE__);
pull(lv);
// debug(__LINE__);
// debug_node(rv);
pull(rv);
// debug(__LINE__);
}
std::pair<int, int> get_value(int v) {
int d = 0;
int x = tree[v].x, y = tree[v].y;
while (tree[v].par != 0) {
v = tree[v].par;
chmax(x, tree[v].lzx);
chmax(y, tree[v].lzy);
d += 1;
}
assert(d <= 100);
return {x, y};
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
int root = 0;
int N, M, Q;
std::cin >> N >> M >> Q;
std::vector<int> ids;
for (int i = 0; i < M; ++i) {
int X, Y;
std::cin >> X >> Y;
int nd = new_node(X, Y);
ids.emplace_back(nd);
int lv, rv;
split_by_x(root, lv, rv, X);
merge(root, lv, nd);
merge(root, root, rv);
}
while (Q--) {
int TP;
std::cin >> TP;
// debug(TP);
if (TP == 1) {
int P;
std::cin >> P;
--P;
auto[x, y] = get_value(ids[P]);
std::cout << x << ' ' << y << '\n';
} else if (TP == 2) {
int X;
std::cin >> X;
int lv, rv;
split_by_y(root, lv, rv, X);
modify(lv, N - X, 0);
super_merge(root, lv, rv);
} else if (TP == 3) {
int X;
std::cin >> X;
int lv, rv;
split_by_x(root, lv, rv, X);
modify(lv, 0, N - X);
merge(root, lv, rv);
} else {
int X, Y;
std::cin >> X >> Y;
int nd = new_node(X, Y);
ids.emplace_back(nd);
int lv, rv;
split_by_x(root, lv, rv, X);
merge(root, lv, nd);
merge(root, root, rv);
}
}
return 0;
}