#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 3e5 + 1;
const int M = 1e6 + 1;
int n, m, q;

int a[N];
int b[N];
int suf[M];

struct Node {
    int l, r;
    int mxm;
    int lzy;
} node[M << 2];

void lazy(int id) {
    int lzy = node[id].lzy;
    if(!lzy) {
        return;
    }
    if(node[id].l != node[id].r) {
        node[l(id)].lzy += lzy;
        node[r(id)].lzy += lzy;
    }
    node[id].mxm += lzy;
    node[id].lzy = 0;
}

void merge(int id, int l, int r) {
    lazy(l), lazy(r);
    node[id].mxm = max(node[l].mxm, node[r].mxm);
}

void build(int id, int l, int r) {
    node[id].l = l;
    node[id].r = r;
    if(l == r) {
        node[id].mxm = suf[l];
        return;
    }
    int q = l + r >> 1;
    build(l(id), l, q);
    build(r(id), q + 1, r);
    merge(id, l(id), r(id));
}

void update(int id, int l, int r, int x) {
    if(node[id].l == l && node[id].r == r) {
        node[id].lzy += x;
        return;
    }
    lazy(id);
    int q = node[id].l + node[id].r >> 1;
    if(l <= q) {
        update(l(id), l, min(q, r), x);
    }
    if(r > q) {
        update(r(id), max(q + 1, l), r, x);
    }
    merge(id, l(id), r(id));
}

int query(int id) {
    lazy(id);
    if(node[id].l == node[id].r) {
        return node[id].l;
    }
    lazy(r(id));
    if(node[r(id)].mxm >= 1) {
        return query(r(id));
    } else {
        return query(l(id));
    }
}

void input() {
    cin >> n >> m;
    for(int i = 1; i <= n; ++i) {
        cin >> a[i];
        suf[a[i]]++;
    }
    for(int i = 1; i <= m; ++i) {
        cin >> b[i];
        suf[b[i]]--;
    }
    for(int i = M - 2; i >= 0; --i) {
        suf[i] += suf[i + 1];
    }
}

void solve() {
    cin >> q;
    build(0, 0, M - 1);
    for(int i = 0; i < q; ++i) {
        int t; cin >> t;
        int k; cin >> k;
        int x; cin >> x;
        if(x == a[k]) {
            int res = query(0);
            if(res) {
                cout << res << "\n";
            } else {
                cout << "-1\n";
            }
            continue;
        }
        if(t == 1) {
            if(x > a[k]) {
                update(0, a[k] + 1, x, 1);
            } else {
                update(0, x + 1, a[k], -1);
            }
            a[k] = x;
        } else {
            if(x > b[k]) {
                update(0, b[k] + 1, x, -1);
            } else {
                update(0, x + 1, b[k], 1);
            }
            b[k] = x;
        }
        int res = query(0);
        if(res) {
            cout << res << "\n";
        } else {
            cout << "-1\n";
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 3e5 + 1;
const int M = 1e6 + 1;
int n, m, q;

int a[N];
int b[N];
int suf[M];

struct Node {
    int l, r;
    int mxm;
    int lzy;
} node[M << 2];

void lazy(int id) {
    int lzy = node[id].lzy;
    if(!lzy) {
        return;
    }
    if(node[id].l != node[id].r) {
        node[l(id)].lzy += lzy;
        node[r(id)].lzy += lzy;
    }
    node[id].mxm += lzy;
    node[id].lzy = 0;
}

void merge(int id, int l, int r) {
    lazy(l), lazy(r);
    node[id].mxm = max(node[l].mxm, node[r].mxm);
}

void build(int id, int l, int r) {
    node[id].l = l;
    node[id].r = r;
    if(l == r) {
        node[id].mxm = suf[l];
        return;
    }
    int q = l + r >> 1;
    build(l(id), l, q);
    build(r(id), q + 1, r);
    merge(id, l(id), r(id));
}

void update(int id, int l, int r, int x) {
    if(node[id].l == l && node[id].r == r) {
        node[id].lzy += x;
        return;
    }
    lazy(id);
    int q = node[id].l + node[id].r >> 1;
    if(l <= q) {
        update(l(id), l, min(q, r), x);
    }
    if(r > q) {
        update(r(id), max(q + 1, l), r, x);
    }
    merge(id, l(id), r(id));
}

int query(int id) {
    lazy(id);
    if(node[id].l == node[id].r) {
        return node[id].l;
    }
    lazy(r(id));
    if(node[r(id)].mxm >= 1) {
        return query(r(id));
    } else {
        return query(l(id));
    }
}

void input() {
    cin >> n >> m;
    for(int i = 1; i <= n; ++i) {
        cin >> a[i];
        suf[a[i]]++;
    }
    for(int i = 1; i <= m; ++i) {
        cin >> b[i];
        suf[b[i]]--;
    }
    for(int i = M - 2; i >= 0; --i) {
        suf[i] += suf[i + 1];
    }
}

void solve() {
    cin >> q;
    build(0, 0, M - 1);
    for(int i = 0; i < q; ++i) {
        int t; cin >> t;
        int k; cin >> k;
        int x; cin >> x;
        if(t == 1) {
            if(x > a[k]) {
                update(0, a[k] + 1, x, 1);
            } else if(x > a[k]) {
                update(0, x + 1, a[k], -1);
            }
            a[k] = x;
        } else {
            if(x > b[k]) {
                update(0, b[k] + 1, x, -1);
            } else if(x < b[k]) {
                update(0, x + 1, b[k], 1);
            }
            b[k] = x;
        }
        int res = query(0);
        if(res) {
            cout << res << "\n";
        } else {
            cout << "-1\n";
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;

int n, m, q, a[maxn], b[maxn], len;
vector<int> e;

struct query {
    //change idx x into y
    int op, x, y;
} qs[maxn];

void prase() {
    sort(e.begin(), e.end());
    e.erase(unique(e.begin(), e.end()), e.end());
    len = e.size();
    for (int i = 1; i <= n; ++i) {
        a[i] = lower_bound(e.begin(), e.end(), a[i]) - e.begin() + 1;
    }
    for (int i = 1; i <= m; ++i) {
        b[i] = lower_bound(e.begin(), e.end(), b[i]) - e.begin() + 1;
    }
    for (int i = 1; i <= q; ++i) {
        qs[i].y = lower_bound(e.begin(), e.end(), qs[i].y) - e.begin() + 1;
    }
}

struct segmentTree {
    int t[maxn << 2], lazy[maxn << 2];

    void pushUp(int i) {
        t[i] = max(t[i << 1], t[i << 1 | 1]);
    }

    void pushDown(int i) {
        if (!lazy[i]) {
            return;
        }
        t[i << 1] += lazy[i];
        t[i << 1 | 1] += lazy[i];
        lazy[i << 1] += lazy[i];
        lazy[i << 1 | 1] += lazy[i];
        lazy[i] = 0;
    }

    void update(int i, int l, int r, int L, int R, int val) {
        if (l >= L && r <= R) {
            t[i] += val;
            lazy[i] += val;
            return;
        }
        pushDown(i);
        int mid = (l + r) >> 1;
        if (L <= mid) {
            update(i << 1, l, mid, L, R, val);
        }
        if (R > mid) {
            update(i << 1 | 1, mid + 1, r, L, R, val);
        }
        pushUp(i);
    }

    int query(int i, int l, int r) {
        if (l == r) {
            return l;
        }
        pushDown(i);
        int mid = (l + r) >> 1;
        if (t[i << 1] >= 1) {
            return query(i << 1, l, mid);
        }
        return query(i << 1 | 1, mid + 1, r);
    }

    void solve() {
        for (int i = 1; i <= n; ++i) {
            update(1, 1, len, 1, a[i], 1);
        }
        for (int i = 1; i <= m; ++i) {
            update(1, 1, len, 1, b[i], -1);
        }
        for (int i = 1; i <= q; ++i) {
            if (qs[i].op == 1) {
                update(1, 1, len, 1, a[qs[i].x], -1);
                update(1, 1, len, 1, qs[i].y, 1);
                if (t[1] < 1) {
                    cout << -1 << '\n';
                    continue;
                }
                cout << e[query(1, 1, len) - 1] << '\n';
            } else {
                update(1, 1, len, 1, b[qs[i].x], 1);
                update(1, 1, len, 1, qs[i].y, -1);
                if (t[1] < 1) {
                    cout << -1 << '\n';
                    continue;
                }
                cout << e[query(1, 1, len) - 1] << '\n';
            }
        }
    }
} segmentTree;

int main() {
    ios::sync_with_stdio(0);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        e.push_back(a[i]);
    }
    for (int i = 1; i <= m; ++i) {
        cin >> b[i];
        e.push_back(b[i]);
    }
    cin >> q;
    for (int i = 1; i <= q; ++i) {
        cin >> qs[i].op >> qs[i].x >> qs[i].y;
        e.push_back(qs[i].y);
    }

    prase();
    segmentTree.solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;

int n, m, q, a[maxn], b[maxn], len;
vector<int> e;

struct query {
    //change idx x into y
    int op, x, y;
} qs[maxn];

void prase() {
    sort(e.begin(), e.end());
    e.erase(unique(e.begin(), e.end()), e.end());
    len = e.size();
    for (int i = 1; i <= n; ++i) {
        a[i] = lower_bound(e.begin(), e.end(), a[i]) - e.begin() + 1;
    }
    for (int i = 1; i <= m; ++i) {
        b[i] = lower_bound(e.begin(), e.end(), b[i]) - e.begin() + 1;
    }
    for (int i = 1; i <= q; ++i) {
        qs[i].y = lower_bound(e.begin(), e.end(), qs[i].y) - e.begin() + 1;
    }
}

struct segmentTree {
    int t[maxn << 2], lazy[maxn << 2];

    void pushUp(int i) {
        t[i] = max(t[i << 1], t[i << 1 | 1]);
    }

    void pushDown(int i) {
        if (!lazy[i]) {
            return;
        }
        t[i << 1] += lazy[i];
        t[i << 1 | 1] += lazy[i];
        lazy[i << 1] += lazy[i];
        lazy[i << 1 | 1] += lazy[i];
        lazy[i] = 0;
    }

    void update(int i, int l, int r, int L, int R, int val) {
        if (l >= L && r <= R) {
            t[i] += val;
            lazy[i] += val;
            return;
        }
        pushDown(i);
        int mid = (l + r) >> 1;
        if (L <= mid) {
            update(i << 1, l, mid, L, R, val);
        }
        if (R > mid) {
            update(i << 1 | 1, mid + 1, r, L, R, val);
        }
        pushUp(i);
    }

    int query(int i, int l, int r) {
        if (l == r) {
            return l;
        }
        pushDown(i);
        int mid = (l + r) >> 1;
        if (t[i << 1 | 1] >= 1) {
            return query(i << 1 | 1, mid + 1, r);
        }
        return query(i << 1, l, mid);
    }

    void solve() {
        for (int i = 1; i <= n; ++i) {
            update(1, 1, len, 1, a[i], 1);
        }
        for (int i = 1; i <= m; ++i) {
            update(1, 1, len, 1, b[i], -1);
        }
        for (int i = 1; i <= q; ++i) {
            if (qs[i].op == 1) {
                update(1, 1, len, 1, a[qs[i].x], -1);
                update(1, 1, len, 1, qs[i].y, 1);
                if (t[1] < 1) {
                    cout << -1 << '\n';
                    continue;
                }
                cout << e[query(1, 1, len) - 1] << '\n';
            } else {
                update(1, 1, len, 1, b[qs[i].x], 1);
                update(1, 1, len, 1, qs[i].y, -1);
                if (t[1] < 1) {
                    cout << -1 << '\n';
                    continue;
                }
                cout << e[query(1, 1, len) - 1] << '\n';
            }
        }
    }
} segmentTree;

int main() {
    ios::sync_with_stdio(0);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        e.push_back(a[i]);
    }
    for (int i = 1; i <= m; ++i) {
        cin >> b[i];
        e.push_back(b[i]);
    }
    cin >> q;
    for (int i = 1; i <= q; ++i) {
        cin >> qs[i].op >> qs[i].x >> qs[i].y;
        e.push_back(qs[i].y);
    }

    prase();
    segmentTree.solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;

int n, m, q, a[maxn], b[maxn], len;
vector<int> e;

struct query {
    //change idx x into y
    int op, x, y;
} qs[maxn];

void prase() {
    sort(e.begin(), e.end());
    e.erase(unique(e.begin(), e.end()), e.end());
    len = e.size();
    for (int i = 1; i <= n; ++i) {
        a[i] = lower_bound(e.begin(), e.end(), a[i]) - e.begin() + 1;
    }
    for (int i = 1; i <= m; ++i) {
        b[i] = lower_bound(e.begin(), e.end(), b[i]) - e.begin() + 1;
    }
    for (int i = 1; i <= q; ++i) {
        qs[i].y = lower_bound(e.begin(), e.end(), qs[i].y) - e.begin() + 1;
    }
}

struct segmentTree {
    int t[maxn << 2], lazy[maxn << 2];

    void pushUp(int i) {
        t[i] = max(t[i << 1], t[i << 1 | 1]);
    }

    void pushDown(int i) {
        if (!lazy[i]) {
            return;
        }
        t[i << 1] += lazy[i];
        t[i << 1 | 1] += lazy[i];
        lazy[i << 1] += lazy[i];
        lazy[i << 1 | 1] += lazy[i];
        lazy[i] = 0;
    }

    void update(int i, int l, int r, int L, int R, int val) {
        if (l >= L && r <= R) {
            t[i] += val;
            lazy[i] += val;
            return;
        }
        pushDown(i);
        int mid = (l + r) >> 1;
        if (L <= mid) {
            update(i << 1, l, mid, L, R, val);
        }
        if (R > mid) {
            update(i << 1 | 1, mid + 1, r, L, R, val);
        }
        pushUp(i);
    }

    int query(int i, int l, int r) {
        if (l == r) {
            return l;
        }
        pushDown(i);
        int mid = (l + r) >> 1;
        if (t[i << 1 | 1] >= 1) {
            return query(i << 1 | 1, mid + 1, r);
        }
        return query(i << 1, l, mid);
    }

    void solve() {
        for (int i = 1; i <= n; ++i) {
            update(1, 1, len, 1, a[i], 1);
        }
        for (int i = 1; i <= m; ++i) {
            update(1, 1, len, 1, b[i], -1);
        }
        for (int i = 1; i <= q; ++i) {
            if (qs[i].op == 1) {
                update(1, 1, len, 1, a[qs[i].x], -1);
                a[qs[i].x] = qs[i].y;
                update(1, 1, len, 1, qs[i].y, 1);
                if (t[1] < 1) {
                    cout << -1 << '\n';
                    continue;
                }
                cout << e[query(1, 1, len) - 1] << '\n';
            } else {
                update(1, 1, len, 1, b[qs[i].x], 1);
                b[qs[i].x] = qs[i].y;
                update(1, 1, len, 1, qs[i].y, -1);
                if (t[1] < 1) {
                    cout << -1 << '\n';
                    continue;
                }
                cout << e[query(1, 1, len) - 1] << '\n';
            }
        }
    }
} segmentTree;

int main() {
    ios::sync_with_stdio(0);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        e.push_back(a[i]);
    }
    for (int i = 1; i <= m; ++i) {
        cin >> b[i];
        e.push_back(b[i]);
    }
    cin >> q;
    for (int i = 1; i <= q; ++i) {
        cin >> qs[i].op >> qs[i].x >> qs[i].y;
        e.push_back(qs[i].y);
    }

    prase();
    segmentTree.solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;

int n, m, q, a[maxn], b[maxn], len;
vector<int> e;

struct query {
    //change idx x into y
    int op, x, y;
} qs[maxn];

void prase() {
    sort(e.begin(), e.end());
    e.erase(unique(e.begin(), e.end()), e.end());
    len = e.size();
    for (int i = 1; i <= n; ++i) {
        a[i] = lower_bound(e.begin(), e.end(), a[i]) - e.begin() + 1;
    }
    for (int i = 1; i <= m; ++i) {
        b[i] = lower_bound(e.begin(), e.end(), b[i]) - e.begin() + 1;
    }
    for (int i = 1; i <= q; ++i) {
        qs[i].y = lower_bound(e.begin(), e.end(), qs[i].y) - e.begin() + 1;
    }
}

struct segmentTree {
    int t[maxn << 2], lazy[maxn << 2];

    void pushUp(int i) {
        t[i] = max(t[i << 1], t[i << 1 | 1]);
    }

    void pushDown(int i) {
        if (!lazy[i]) {
            return;
        }
        t[i << 1] += lazy[i];
        t[i << 1 | 1] += lazy[i];
        lazy[i << 1] += lazy[i];
        lazy[i << 1 | 1] += lazy[i];
        lazy[i] = 0;
    }

    void update(int i, int l, int r, int L, int R, int val) {
        if (l >= L && r <= R) {
            t[i] += val;
            lazy[i] += val;
            return;
        }
        pushDown(i);
        int mid = (l + r) >> 1;
        if (L <= mid) {
            update(i << 1, l, mid, L, R, val);
        }
        if (R > mid) {
            update(i << 1 | 1, mid + 1, r, L, R, val);
        }
        pushUp(i);
    }

    int query(int i, int l, int r) {
        if (l == r) {
            return l;
        }
        pushDown(i);
        int mid = (l + r) >> 1;
        if (t[i << 1 | 1] >= 1) {
            return query(i << 1 | 1, mid + 1, l);
        }
        return query(i << 1, l, mid);
    }

    void solve() {
        for (int i = 1; i <= n; ++i) {
            update(1, 1, len, 1, a[i], 1);
        }
        for (int i = 1; i <= m; ++i) {
            update(1, 1, len, 1, b[i], -1);
        }
        for (int i = 1; i <= q; ++i) {
            if (qs[i].op == 1) {
                update(1, 1, len, 1, a[qs[i].x], -1);
                a[qs[i].x] = qs[i].y;
                update(1, 1, len, 1, qs[i].y, 1);
                if (t[1] < 1) {
                    cout << -1 << '\n';
                    continue;
                }
                cout << e[query(1, 1, len) - 1] << '\n';
            } else {
                update(1, 1, len, 1, b[qs[i].x], 1);
                b[qs[i].x] = qs[i].y;
                update(1, 1, len, 1, qs[i].y, -1);
                if (t[1] < 1) {
                    cout << -1 << '\n';
                    continue;
                }
                cout << e[query(1, 1, len) - 1] << '\n';
            }
        }
    }
} segmentTree;

int main() {
    ios::sync_with_stdio(0);
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        e.push_back(a[i]);
    }
    for (int i = 1; i <= m; ++i) {
        cin >> b[i];
        e.push_back(b[i]);
    }
    cin >> q;
    for (int i = 1; i <= q; ++i) {
        cin >> qs[i].op >> qs[i].x >> qs[i].y;
        e.push_back(qs[i].y);
    }

    prase();
    segmentTree.solve();
    return 0;
}


#ifndef LOCAL
#define NDEBUG
#endif
#include<cassert>
#include<climits>
#include<array>
#include<vector>
#include<iostream>

struct ST{
	struct node{
		int lazy,min;
		int getmin()const{
			// real min value after pushing lazy, assume ancestor lazy values = 0
			return lazy+min;
		}
	};
	std::vector<node> d;
	ST(int n):d(2*n+2){
		for(int i=(int)d.size()-1;i;i>>=1)
			d[i].min=INT_MIN;
	}

	void add(int l,int r,int delta){
		if(l==r)return;
		assert(l<r);

		l+=int(d.size()/2);
		r+=int(d.size()/2);
		std::array<int,2> stored_endpts{{l,r-1}};
		while(l<r){
			if(l&1) d[l++].lazy+=delta;
			if(r&1) d[--r].lazy+=delta;
			l>>=1;r>>=1;
		}
		for(int x:stored_endpts)
			for(int y=x>>1;y;y>>=1)
				d[y].min=std::min(d[y*2].getmin(),d[y*2+1].getmin());
	}

	void pushlazy(int node){
		if(d[node].lazy){
			d[node].min+=d[node].lazy;
			d[node*2].lazy+=d[node].lazy;
			d[node*2+1].lazy+=d[node].lazy;
			d[node].lazy=0;
		}
	}

	int prevlt(int x,int val){
		assert(x>=0);
		x+=int(d.size()/2);
		assert(x<(int)d.size()-1);

		for(int sh=31^__builtin_clz(x);sh;--sh)
			pushlazy(x>>sh);

		while(d[x].getmin()>=val){
			if(x&1)
				x>>=1;
			else{
				x>>=__builtin_ctz(x);
				if(x>1) --x;
			}
		}

		while(x<int(d.size()/2)){
			pushlazy(x);
			x=x*2;
			if(d[x+1].getmin()<val) ++x;
			assert(d[x].getmin()<val);
		}

		if(x==(int)d.size()-1)return -1;
		return x-int(d.size()/2);
	}
};

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int ndish,npupil;std::cin>>ndish>>npupil;
	int constexpr TSIZE=2000003;
	ST t(TSIZE);

	std::vector<int> dishv(ndish),pupilv(npupil);
	for(int& ai:dishv){
		std::cin>>ai;
		t.add(2*ai+1,TSIZE,1);
	}
	for(int& bi:pupilv){
		std::cin>>bi;
		t.add(2*bi+2,TSIZE,-1);
	}

	int nq;std::cin>>nq;
	while(nq--){
		char type;int i;
		std::cin>>type>>i;
		--i;

		if(type=='1'){
			auto& ai=dishv[i];
			t.add(2*ai+1,TSIZE,-1);
			std::cin>>ai;
			t.add(2*ai+1,TSIZE,1);
		}else{
			assert(type=='2');
			auto& bi=pupilv[i];
			t.add(2*bi+2,TSIZE,1);
			std::cin>>bi;
			t.add(2*bi+2,TSIZE,-1);
		}

		assert(t.prevlt(TSIZE-1,ndish-npupil+1)==TSIZE-1);
		int out=t.prevlt(TSIZE-1,ndish-npupil);
		assert(out<TSIZE-1);
		if(out<0){
			assert(out==-1);
			std::cout<<"-1\n";
		}else{
			assert(out%2==0);
			std::cout<<out/2<<'\n';
		}
	}
}


// constant optimization. (I did not try to generate test to find out bottleneck)
// But... why do I focus on being fast so much while it's much more common to get WA/no-idea instead of
// TLE at the IOI...
#ifndef LOCAL
#define NDEBUG
#endif
#include<cassert>
#include<climits>
#include<array>
#include<vector>
#include<iostream>

struct ST{
	struct node{
		int lazy,min;
		int getmin()const{
			// real min value after pushing lazy, assume ancestor lazy values = 0
			return lazy+min;
		}
	};
	std::vector<node> d;
	ST(int n):d(2*n+2){
		for(int i=(int)d.size()-1;i;i>>=1)
			d[i].min=INT_MIN;
	}

	void add(int l,int r,int delta){
		if(l==r)return;
		assert(l<r);

		l+=int(d.size()/2);
		r+=int(d.size()/2);
		std::array<int,2> stored_endpts{{l,r-1}};
		while(l<r){
			if(l&1) d[l++].lazy+=delta;
			if(r&1) d[--r].lazy+=delta;
			l>>=1;r>>=1;
		}
		for(int x:stored_endpts)
			for(int y=x>>1;y;y>>=1)
				d[y].min=std::min(d[y*2].getmin(),d[y*2+1].getmin());
	}

	void pushlazy(int node){
		if(d[node].lazy){
			d[node].min+=d[node].lazy;
			d[node*2].lazy+=d[node].lazy;
			d[node*2+1].lazy+=d[node].lazy;
			d[node].lazy=0;
		}
	}

	int prevlt(int x,int val){
		assert(x>=0);
		x+=int(d.size()/2);
		assert(x<(int)d.size()-1);

		for(int sh=31^__builtin_clz(x);sh;--sh)
			pushlazy(x>>sh);

		while(d[x].getmin()>=val){
			if(x&1)
				x>>=1;
			else{
				x>>=__builtin_ctz(x);
				if(x>1) --x;
			}
		}

		while(x<int(d.size()/2)){
			pushlazy(x);
			x=x*2;
			if(d[x+1].getmin()<val) ++x;
			assert(d[x].getmin()<val);
		}

		if(x==(int)d.size()-1)return -1;
		return x-int(d.size()/2);
	}
};

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int ndish,npupil;std::cin>>ndish>>npupil;
	int constexpr TSIZE=1000003;
	ST t(TSIZE);

	std::vector<int> dishv(ndish),pupilv(npupil);
	// internal access to the segment tree data array (not recommended)
	for(int& ai:dishv){
		std::cin>>ai;
		++t.d[t.d.size()/2+ai].min;
	}
	for(int& bi:pupilv){
		std::cin>>bi;
		--t.d[t.d.size()/2+bi].min;
	}
	for(auto x=t.d.size()/2;x<t.d.size()-2;++x)
		t.d[x+1].min+=t.d[x].min;
	for(auto x=t.d.size()/2;--x;)
		t.d[x].min=std::min(t.d[x*2].min,t.d[x*2+1].min);

	int nq;std::cin>>nq;
	while(nq--){
		char type;int i;
		std::cin>>type>>i;
		--i;

		if(type=='1'){
			auto& ai=dishv[i];
			auto old=ai;
			std::cin>>ai;
			if(old<ai) t.add(old,ai,-1);
			else if(old>ai) t.add(ai,old,1);
		}else{
			assert(type=='2');
			auto& bi=pupilv[i];
			auto old=bi;
			std::cin>>bi;
			if(old<bi) t.add(old,bi,1);
			else if(old>bi) t.add(bi,old,-1);
		}

		assert(t.prevlt(TSIZE-1,ndish-npupil+1)==TSIZE-1);
		int out=t.prevlt(TSIZE-1,ndish-npupil);
		assert(out<TSIZE-1);
		if(out<0){
			assert(out==-1);
			std::cout<<"-1\n";
		}else{
			std::cout<<out+1<<'\n';
		}
	}
}


#ifndef LOCAL
#define NDEBUG
#endif
#include<cassert>
#include<climits>
#include<array>
#include<vector>

namespace io{ // https://codeforces.com/contest/1179/submission/55932144

using namespace std;

/** Fast input-output */

template <class T = int> inline T readInt();
inline double readDouble();
inline int readUInt();
inline int readChar(); // first non-blank character
inline void readWord(char *s);
inline bool readLine(char *s); // do not save '\n'
inline bool isEof();
inline int getChar();
inline int peekChar();
inline bool seekEof();
inline void skipBlanks();

template <class T> inline void writeInt(T x, char end = 0, int len = -1);
inline void writeChar(int x);
inline void writeWord(const char *s);
inline void writeDouble(double x, int len = 0);
inline void flush();

static struct buffer_flusher_t {
	~buffer_flusher_t() {
		flush();
	}
} buffer_flusher;

/** Read */

static const int buf_size = 4096;

static unsigned char buf[buf_size];
static int buf_len = 0, buf_pos = 0;

inline bool isEof() {
	if (buf_pos == buf_len) {
		buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
		if (buf_pos == buf_len)
			return 1;
	}
	return 0;
}

inline int getChar() {
	return isEof() ? -1 : buf[buf_pos++];
}

inline int peekChar() {
	return isEof() ? -1 : buf[buf_pos];
}

inline bool seekEof() {
	int c;
	while ((c = peekChar()) != -1 && c <= 32)
		buf_pos++;
	return c == -1;
}

inline void skipBlanks() {
	while (!isEof() && buf[buf_pos] <= 32U)
		buf_pos++;
}

inline int readChar() {
	int c = getChar();
	while (c != -1 && c <= 32)
		c = getChar();
	return c;
}

inline int readUInt() {
	int c = readChar(), x = 0;
	while ('0' <= c && c <= '9')
		x = x * 10 + c - '0', c = getChar();
	return x;
}

template <class T>
inline T readInt() {
	int s = 1, c = readChar();
	T x = 0;
	if (c == '-')
		s = -1, c = getChar();
	else if (c == '+')
		c = getChar();
	while ('0' <= c && c <= '9')
		x = x * 10 + c - '0', c = getChar();
	return s == 1 ? x : -x;
}

inline double readDouble() {
	int s = 1, c = readChar();
	double x = 0;
	if (c == '-')
		s = -1, c = getChar();
	while ('0' <= c && c <= '9')
		x = x * 10 + c - '0', c = getChar();
	if (c == '.') {
		c = getChar();
		double coef = 1;
		while ('0' <= c && c <= '9')
			x += (c - '0') * (coef *= 1e-1), c = getChar();
	}
	return s == 1 ? x : -x;
}

inline void readWord(char *s) {
	int c = readChar();
	while (c > 32)
		*s++ = c, c = getChar();
	*s = 0;
}

inline bool readLine(char *s) {
	int c = getChar();
	while (c != '\n' && c != -1)
		*s++ = c, c = getChar();
	*s = 0;
	return c != -1;
}

/** Write */

static int write_buf_pos = 0;
static char write_buf[buf_size];

inline void writeChar(int x) {
	if (write_buf_pos == buf_size)
		fwrite(write_buf, 1, buf_size, stdout), write_buf_pos = 0;
	write_buf[write_buf_pos++] = x;
}

inline void flush() {
	if (write_buf_pos) {
		fwrite(write_buf, 1, write_buf_pos, stdout), write_buf_pos = 0;
		fflush(stdout);
	}
}

template <class T>
inline void writeInt(T x, char end, int output_len) {
	if (x < 0)
		writeChar('-'), x = -x;

	char s[24];
	int n = 0;
	while (x || !n)
		s[n++] = '0' + x % 10, x /= 10;
	while (n < output_len)
		s[n++] = '0';
	while (n--)
		writeChar(s[n]);
	if (end)
		writeChar(end);
}

inline void writeWord(const char *s) {
	while (*s)
		writeChar(*s++);
}

inline void writeDouble(double x, int output_len) {
	if (x < 0)
		writeChar('-'), x = -x;
	int t = (int)x;
	writeInt(t), x -= t;
	writeChar('.');
	for (int i = output_len - 1; i > 0; i--) {
		x *= 10;
		t = std::min(9, (int)x);
		writeChar('0' + t), x -= t;
	}
	x *= 10;
	t = std::min(9, (int)(x + 0.5));
	writeChar('0' + t);
}
};

struct ST{
	struct node{
		int lazy,min;
		int getmin()const{
			// real min value after pushing lazy, assume ancestor lazy values = 0
			return lazy+min;
		}
	};
	std::vector<node> d;
	ST(int n):d(2*n){}

	void add(int l,int r,int delta){
		if(l==r)return;
		assert(l<r);

		l+=int(d.size()/2);
		r+=int(d.size()/2);
		std::array<int,2> stored_endpts{{l,r-1}};
		while(l<r){
			if(l&1) d[l++].lazy+=delta;
			if(r&1) d[--r].lazy+=delta;
			l>>=1;r>>=1;
		}
		for(int x:stored_endpts)
			for(int y=x>>1;y;y>>=1)
				d[y].min=std::min(d[y*2].getmin(),d[y*2+1].getmin());
	}

	void pushlazy(int node){
		if(d[node].lazy){
			d[node].min+=d[node].lazy;
			d[node*2].lazy+=d[node].lazy;
			d[node*2+1].lazy+=d[node].lazy;
			d[node].lazy=0;
		}
	}

	int prevlt(int x,int val){
		assert(x>=0 and x<int(d.size()/2));

		int l=int(d.size()/2),r=int(d.size()/2)+x+1;
		for(int y:{l,r-1})
			for(int sh=31^__builtin_clz(x);sh;--sh)
				pushlazy(y>>sh);

		x=-1;
		while(l<r){
			if(l&1){
				if(d[l].getmin()<val)x=l;
				++l;
			}
			if(r&1){
				--r;
				if(d[r].getmin()<val){ x=r;break; }
			}
			l>>=1;r>>=1;
		}
		if(x<0)return -1;

		while(x<int(d.size()/2)){
			pushlazy(x);
			x=x*2;
			if(d[x+1].getmin()<val) ++x;
			assert(d[x].getmin()<val);
		}

		return x-int(d.size()/2);
	}
};

int main(){
	int ndish=io::readUInt(),npupil=io::readUInt();
	int constexpr TSIZE=1000003;
	ST t(TSIZE);

	std::vector<int> dishv(ndish),pupilv(npupil);
	// internal access to the segment tree data array (not recommended)
	for(int& ai:dishv){
		ai=io::readUInt();
		++t.d[t.d.size()/2+ai].min;
	}
	for(int& bi:pupilv){
		bi=io::readUInt();
		--t.d[t.d.size()/2+bi].min;
	}
	for(auto x=t.d.size()/2;x<t.d.size()-1;++x)
		t.d[x+1].min+=t.d[x].min;
	for(auto x=t.d.size()/2;--x;)
		t.d[x].min=std::min(t.d[x*2].min,t.d[x*2+1].min);

	int nq=io::readUInt();
	while(nq--){
		char type=io::readChar();int i=io::readUInt();
		--i;

		if(type=='1'){
			auto& ai=dishv[i];
			auto old=ai;
			ai=io::readUInt();
			if(old<ai) t.add(old,ai,-1);
			else if(old>ai) t.add(ai,old,1);
		}else{
			assert(type=='2');
			auto& bi=pupilv[i];
			auto old=bi;
			bi=io::readUInt();
			if(old<bi) t.add(old,bi,1);
			else if(old>bi) t.add(bi,old,-1);
		}

		assert(t.prevlt(TSIZE-1,ndish-npupil+1)==TSIZE-1);
		int out=t.prevlt(TSIZE-1,ndish-npupil);
		assert(out<TSIZE-1);
		if(out<0){
			assert(out==-1);
			io::writeChar('-');
			io::writeChar('1');
			io::writeChar('\n');
		}else{
			io::writeInt(out+1);
			io::writeChar('\n');
		}
	}
}


// I spent a lot of time trying to solve D before realize that D is l)ely harder.
// (I already have almost the complete solution for D by now)
#ifndef LOCAL
#define NDEBUG
#endif
#include<cassert>
#include<vector>
#include<iostream>

struct ST{
	struct node{
		int lazy,min;
		int getmin()const{
			// real min value after pushing lazy, assume ancestor lazy values = 0
			return lazy+min;
		}
	};
	int arraysize;
	std::vector<node> d;
	ST(int n):arraysize(n),d(n*4+4){}

	void add(int l,int r,int delta){
		assert(0<=l and l<=r and r<=arraysize);
		add(l,r,delta, 1,0,arraysize);
	}

	void add(int l,int r,int delta, int node,int nodel,int noder){
		if(l<=nodel and noder<=r){ d[node].lazy+=delta; return; }
		if(noder<=l or r<=nodel)return;
		int const mid=(nodel+noder)>>1;
		add(l,r,delta, node*2,nodel,mid);
		add(l,r,delta, node*2+1,mid,noder);
		d[node].min=std::min(d[node*2].getmin(),d[node*2+1].getmin());
	}

	int prevlt(int x,int val){
		assert(0<=x and x<arraysize);
		return prevlt(x,val, 1,0,arraysize);
	}

	int prevlt(int x,int val, int node,int nodel,int noder){
		if(x<nodel or d[node].getmin()>=val)return -1;
		if(noder-nodel==1){
			assert(d[node].getmin()<val);
			return nodel;
		}

		if(d[node].lazy){
			d[node].min+=d[node].lazy;
			d[node*2].lazy+=d[node].lazy;
			d[node*2+1].lazy+=d[node].lazy;
			d[node].lazy=0;
		}
		int const mid=(nodel+noder)>>1;
		int out=prevlt(x,val, node*2+1,mid,noder);
		if(out<0)out=prevlt(x,val, node*2,nodel,mid);
		return out;
	}
};

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int ndish,npupil;std::cin>>ndish>>npupil;
	int constexpr TSIZE=2000003;
	ST t(TSIZE);

	std::vector<int> dishv(ndish),pupilv(npupil);
	for(int& ai:dishv){
		std::cin>>ai;
		t.add(2*ai+1,TSIZE,1);
	}
	for(int& bi:pupilv){
		std::cin>>bi;
		t.add(2*bi+2,TSIZE,-1);
	}

	int nq;std::cin>>nq;
	while(nq--){
		char type;int i;
		std::cin>>type>>i;
		--i;

		if(type=='1'){
			auto& ai=dishv[i];
			t.add(2*ai+1,TSIZE,-1);
			std::cin>>ai;
			t.add(2*ai+1,TSIZE,1);
		}else{
			assert(type=='2');
			auto& bi=pupilv[i];
			t.add(2*bi+2,TSIZE,1);
			std::cin>>bi;
			t.add(2*bi+2,TSIZE,-1);
		}

		assert(t.prevlt(TSIZE-1,ndish-npupil+1)==TSIZE-1);
		int out=t.prevlt(TSIZE-1,ndish-npupil);
		assert(out<TSIZE-1);
		if(out<0){
			assert(out==-1);
			std::cout<<"-1\n";
		}else{
			assert(out%2==0);
			std::cout<<out/2<<'\n';
		}
	}
}


// constant optimization. (I did not try to generate test to find out bottleneck)
// But... why do I focus on being fast so much while it's much more common to get WA/no-idea instead of
// TLE at the IOI...
#ifndef LOCAL
#define NDEBUG
#endif
#include<cassert>
#include<climits>
#include<array>
#include<vector>

namespace io{ // https://codeforces.com/contest/1179/submission/55932144

using namespace std;

/** Fast input-output */

template <class T = int> inline T readInt();
inline double readDouble();
inline int readUInt();
inline int readChar(); // first non-blank character
inline void readWord(char *s);
inline bool readLine(char *s); // do not save '\n'
inline bool isEof();
inline int getChar();
inline int peekChar();
inline bool seekEof();
inline void skipBlanks();

template <class T> inline void writeInt(T x, char end = 0, int len = -1);
inline void writeChar(int x);
inline void writeWord(const char *s);
inline void writeDouble(double x, int len = 0);
inline void flush();

static struct buffer_flusher_t {
	~buffer_flusher_t() {
		flush();
	}
} buffer_flusher;

/** Read */

static const int buf_size = 4096;

static unsigned char buf[buf_size];
static int buf_len = 0, buf_pos = 0;

inline bool isEof() {
	if (buf_pos == buf_len) {
		buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
		if (buf_pos == buf_len)
			return 1;
	}
	return 0;
}

inline int getChar() {
	return isEof() ? -1 : buf[buf_pos++];
}

inline int peekChar() {
	return isEof() ? -1 : buf[buf_pos];
}

inline bool seekEof() {
	int c;
	while ((c = peekChar()) != -1 && c <= 32)
		buf_pos++;
	return c == -1;
}

inline void skipBlanks() {
	while (!isEof() && buf[buf_pos] <= 32U)
		buf_pos++;
}

inline int readChar() {
	int c = getChar();
	while (c != -1 && c <= 32)
		c = getChar();
	return c;
}

inline int readUInt() {
	int c = readChar(), x = 0;
	while ('0' <= c && c <= '9')
		x = x * 10 + c - '0', c = getChar();
	return x;
}

template <class T>
inline T readInt() {
	int s = 1, c = readChar();
	T x = 0;
	if (c == '-')
		s = -1, c = getChar();
	else if (c == '+')
		c = getChar();
	while ('0' <= c && c <= '9')
		x = x * 10 + c - '0', c = getChar();
	return s == 1 ? x : -x;
}

inline double readDouble() {
	int s = 1, c = readChar();
	double x = 0;
	if (c == '-')
		s = -1, c = getChar();
	while ('0' <= c && c <= '9')
		x = x * 10 + c - '0', c = getChar();
	if (c == '.') {
		c = getChar();
		double coef = 1;
		while ('0' <= c && c <= '9')
			x += (c - '0') * (coef *= 1e-1), c = getChar();
	}
	return s == 1 ? x : -x;
}

inline void readWord(char *s) {
	int c = readChar();
	while (c > 32)
		*s++ = c, c = getChar();
	*s = 0;
}

inline bool readLine(char *s) {
	int c = getChar();
	while (c != '\n' && c != -1)
		*s++ = c, c = getChar();
	*s = 0;
	return c != -1;
}

/** Write */

static int write_buf_pos = 0;
static char write_buf[buf_size];

inline void writeChar(int x) {
	if (write_buf_pos == buf_size)
		fwrite(write_buf, 1, buf_size, stdout), write_buf_pos = 0;
	write_buf[write_buf_pos++] = x;
}

inline void flush() {
	if (write_buf_pos) {
		fwrite(write_buf, 1, write_buf_pos, stdout), write_buf_pos = 0;
		fflush(stdout);
	}
}

template <class T>
inline void writeInt(T x, char end, int output_len) {
	if (x < 0)
		writeChar('-'), x = -x;

	char s[24];
	int n = 0;
	while (x || !n)
		s[n++] = '0' + x % 10, x /= 10;
	while (n < output_len)
		s[n++] = '0';
	while (n--)
		writeChar(s[n]);
	if (end)
		writeChar(end);
}

inline void writeWord(const char *s) {
	while (*s)
		writeChar(*s++);
}

inline void writeDouble(double x, int output_len) {
	if (x < 0)
		writeChar('-'), x = -x;
	int t = (int)x;
	writeInt(t), x -= t;
	writeChar('.');
	for (int i = output_len - 1; i > 0; i--) {
		x *= 10;
		t = std::min(9, (int)x);
		writeChar('0' + t), x -= t;
	}
	x *= 10;
	t = std::min(9, (int)(x + 0.5));
	writeChar('0' + t);
}
};

struct ST{
	struct node{
		int lazy,min;
		int getmin()const{
			// real min value after pushing lazy, assume ancestor lazy values = 0
			return lazy+min;
		}
	};
	std::vector<node> d;
	ST(int n):d(2*n+2){
		for(int i=(int)d.size()-1;i;i>>=1)
			d[i].min=INT_MIN;
	}

	void add(int l,int r,int delta){
		if(l==r)return;
		assert(l<r);

		l+=int(d.size()/2);
		r+=int(d.size()/2);
		std::array<int,2> stored_endpts{{l,r-1}};
		while(l<r){
			if(l&1) d[l++].lazy+=delta;
			if(r&1) d[--r].lazy+=delta;
			l>>=1;r>>=1;
		}
		for(int x:stored_endpts)
			for(int y=x>>1;y;y>>=1)
				d[y].min=std::min(d[y*2].getmin(),d[y*2+1].getmin());
	}

	void pushlazy(int node){
		if(d[node].lazy){
			d[node].min+=d[node].lazy;
			d[node*2].lazy+=d[node].lazy;
			d[node*2+1].lazy+=d[node].lazy;
			d[node].lazy=0;
		}
	}

	int prevlt(int x,int val){
		assert(x>=0);
		x+=int(d.size()/2);
		assert(x<(int)d.size()-1);

		for(int sh=31^__builtin_clz(x);sh;--sh)
			pushlazy(x>>sh);

		while(d[x].getmin()>=val){
			if(x&1)
				x>>=1;
			else{
				x>>=__builtin_ctz(x);
				if(x>1) --x;
			}
		}

		while(x<int(d.size()/2)){
			pushlazy(x);
			x=x*2;
			if(d[x+1].getmin()<val) ++x;
			assert(d[x].getmin()<val);
		}

		if(x==(int)d.size()-1)return -1;
		return x-int(d.size()/2);
	}
};

int main(){
	int ndish=io::readUInt(),npupil=io::readUInt();
	int constexpr TSIZE=1000003;
	ST t(TSIZE);

	std::vector<int> dishv(ndish),pupilv(npupil);
	// internal access to the segment tree data array (not recommended)
	for(int& ai:dishv){
		ai=io::readUInt();
		++t.d[t.d.size()/2+ai].min;
	}
	for(int& bi:pupilv){
		bi=io::readUInt();
		--t.d[t.d.size()/2+bi].min;
	}
	for(auto x=t.d.size()/2;x<t.d.size()-2;++x)
		t.d[x+1].min+=t.d[x].min;
	for(auto x=t.d.size()/2;--x;)
		t.d[x].min=std::min(t.d[x*2].min,t.d[x*2+1].min);

	int nq=io::readUInt();
	while(nq--){
		char type=io::readChar();int i=io::readUInt();
		--i;

		if(type=='1'){
			auto& ai=dishv[i];
			auto old=ai;
			ai=io::readUInt();
			if(old<ai) t.add(old,ai,-1);
			else if(old>ai) t.add(ai,old,1);
		}else{
			assert(type=='2');
			auto& bi=pupilv[i];
			auto old=bi;
			bi=io::readUInt();
			if(old<bi) t.add(old,bi,1);
			else if(old>bi) t.add(bi,old,-1);
		}

		assert(t.prevlt(TSIZE-1,ndish-npupil+1)==TSIZE-1);
		int out=t.prevlt(TSIZE-1,ndish-npupil);
		assert(out<TSIZE-1);
		if(out<0){
			assert(out==-1);
			io::writeChar('-');
			io::writeChar('1');
			io::writeChar('\n');
		}else{
			io::writeInt(out+1);
			io::writeChar('\n');
		}
	}
}


#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define all(x)          x.begin(), x.end()
#define sz(x)           (int)x.size()
#define pb              push_back

#define ll              long long
// #define int             long long

template <typename T>
using ordered_set = tree<T, null_type,
      less<T>, rb_tree_tag,
      tree_order_statistics_node_update>;

const int MOD1 = 1000000007;
const int MOD2 = 998244353;
const double PI = acos(-1.0);
const int N = 1e6 + 10;

const int32_t maxn = N;

struct node
{
	int val = 0;
	int lazy = 0;
	bool islazy = false;
	// only used to assign value to leaf nodes in build and pupd
	void assign(int val) {
		this -> val += val;
	}
	// used in build, rquery, pupd, rupd
	void merge(node &l, node &r) {
		val = min(l.val, r.val);
	}
};

struct SegTree
{
	int32_t len = 0;
	node zero;
	vector<node> t;

	SegTree (int32_t _len) {
		len = _len;
		t.resize((len << 2) + 10);
	}
	SegTree () {
		len = maxn;
		t.resize((len << 2) + 10);
	}

	//if a node has lazy tag then its info is correct but its children's info
	//is old, so pushdown() before going into children
	inline void pushdown(int32_t v, int32_t tl, int32_t tr) {
		if (!t[v].islazy) { return; }

		int32_t tm = (tl + tr) >> 1;
		apply((v << 1), tl, tm, t[v].lazy);
		apply(((v << 1) | 1), tm + 1, tr, t[v].lazy);

		t[v].lazy = zero.lazy;
		t[v].islazy = false;
		return;
	}
	//apply() is an auxillary function to apply range update and set lazy tag
	inline void apply(int32_t v, int32_t tl, int32_t tr, int val) {
		if (tl != tr) {
			t[v].lazy += val;				// modify the lazy by val, eg. lazy += val
			t[v].islazy = true;
		}
		// incorporate the change (=val) in node
		t[v].val += val;
		return;
	}
	void build(int a[], int32_t v, int32_t tl, int32_t tr) {
		if (tl == tr) {
			t[v].assign(a[tl]);
			return;
		}
		int32_t tm = (tl + tr) >> 1;
		build(a, (v << 1), tl, tm);
		build(a, ((v << 1) | 1), tm + 1, tr);
		t[v].merge(t[(v << 1)], t[((v << 1) | 1)]);
		return;
	}
	void build(int a[]) {
		build(a, 1, 0, len - 1);
		return;
	}
	node pquery(int32_t v, int32_t tl, int32_t tr, int32_t pos) {
		if (tl == tr) {
			return t[v];
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		if (pos <= tm) {
			return pquery((v << 1), tl, tm, pos);
		}
		else {
			return pquery(((v << 1) | 1), tm + 1, tr, pos);
		}
	}
	node pquery(int32_t pos) {
		return pquery(1, 0, len - 1, pos);
	}
	node rquery(int32_t v, int32_t tl, int32_t tr, int32_t l, int32_t r) {
		if (l > tr || r < tl) {
			return zero;
		}
		if (l <= tl && tr <= r) {
			return t[v];
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		node a, b, ans;
		a = rquery((v << 1), tl, tm, l, r);
		b = rquery(((v << 1) | 1), tm + 1, tr, l, r);
		ans.merge(a, b);
		return ans;
	}
	node rquery(int32_t l, int32_t r) {
		return rquery(1, 0, len - 1, l, r);
	}
	void pupd(int32_t v, int32_t tl, int32_t tr, int32_t pos, int val) {
		if (tl == tr) {
			t[v].assign(val);
			return;
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		if (pos <= tm) {
			pupd((v << 1), tl, tm, pos, val);
		}
		else {
			pupd(((v << 1) | 1), tm + 1, tr, pos, val);
		}
		t[v].merge(t[(v << 1)], t[((v << 1) | 1)]);
		return;
	}
	void pupd(int32_t pos, int val) {
		pupd(1, 0, len - 1, pos, val);
		return;
	}
	void rupd(int32_t v, int32_t tl, int32_t tr, int32_t l, int32_t r, int val) {
		if (l > tr || r < tl) {
			return;
		}
		if (l <= tl && tr <= r) {
			apply(v, tl, tr, val);
			return;
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		rupd((v << 1), tl, tm, l, r, val);
		rupd(((v << 1) | 1), tm + 1, tr, l, r, val);
		t[v].merge(t[(v << 1)], t[((v << 1) | 1)]);
		return;
	}
	void rupd(int32_t l, int32_t r, int val) {
		rupd(1, 0, len - 1, l, r, val);
	}

	int find_last_negative(int v, int tl, int tr) {
		if (t[v].val >= 0) {
			return -1;
		}
		if (tl == tr) {
			return tl;
		}
		pushdown(v, tl, tr);
		int tm = (tl + tr) >> 1;
		if (t[(v << 1) | 1].val < 0) {
			return find_last_negative((v << 1) | 1, tm + 1, tr);
		}
		return find_last_negative((v << 1), tl, tm);
	}
	int find_last_negative() {
		return find_last_negative(1, 0, len - 1);
	}
};

SegTree st;

void solve() {
	int n, m;
	cin >> n >> m;

	int a[n], b[m];
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
		st.rupd(0, a[i], -1);
	}

	for (int i = 0; i < m; ++i) {
		cin >> b[i];
		st.rupd(0, b[i], 1);
	}

	int q;
	cin >> q;
	while (q--) {
		int t;
		cin >> t;
		if (t == 1) {
			int i, x;
			cin >> i >> x;
			i--;
			st.rupd(0, a[i], 1);
			a[i] = x;
			st.rupd(0, a[i], -1);
		} else {
			int i, x;
			cin >> i >> x;
			i--;
			st.rupd(0, b[i], -1);
			b[i] = x;
			st.rupd(0, b[i], 1);
		}
		cout << st.find_last_negative() << '\n';
	}

}

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int t = 1;
	// cin >> t;
	while (t--) {
		solve();
		cout << '\n';
	}
	return 0;
}


#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define all(x)          x.begin(), x.end()
#define sz(x)           (int)x.size()
#define pb              push_back

#define ll              long long
#define int             long long

template <typename T>
using ordered_set = tree<T, null_type,
      less<T>, rb_tree_tag,
      tree_order_statistics_node_update>;

const int MOD1 = 1000000007;
const int MOD2 = 998244353;
const double PI = acos(-1.0);
const int N = 1e6 + 10;

const int32_t maxn = N;

struct node
{
	int val = 0;
	int lazy = 0;
	bool islazy = false;
	// only used to assign value to leaf nodes in build and pupd
	void assign(int val) {
		this -> val += val;
	}
	// used in build, rquery, pupd, rupd
	void merge(node &l, node &r) {
		val = min(l.val, r.val);
	}
};

struct SegTree
{
	int32_t len = 0;
	node zero;
	vector<node> t;

	SegTree (int32_t _len) {
		len = _len;
		t.resize((len << 2) + 10);
	}
	SegTree () {
		len = maxn;
		t.resize((len << 2) + 10);
	}

	//if a node has lazy tag then its info is correct but its children's info
	//is old, so pushdown() before going into children
	inline void pushdown(int32_t v, int32_t tl, int32_t tr) {
		if (!t[v].islazy) { return; }

		int32_t tm = (tl + tr) >> 1;
		apply((v << 1), tl, tm, t[v].lazy);
		apply(((v << 1) | 1), tm + 1, tr, t[v].lazy);

		t[v].lazy = zero.lazy;
		t[v].islazy = false;
		return;
	}
	//apply() is an auxillary function to apply range update and set lazy tag
	inline void apply(int32_t v, int32_t tl, int32_t tr, int val) {
		if (tl != tr) {
			t[v].lazy += val;				// modify the lazy by val, eg. lazy += val
			t[v].islazy = true;
		}
		// incorporate the change (=val) in node
		t[v].val += val;
		return;
	}
	void build(int a[], int32_t v, int32_t tl, int32_t tr) {
		if (tl == tr) {
			t[v].assign(a[tl]);
			return;
		}
		int32_t tm = (tl + tr) >> 1;
		build(a, (v << 1), tl, tm);
		build(a, ((v << 1) | 1), tm + 1, tr);
		t[v].merge(t[(v << 1)], t[((v << 1) | 1)]);
		return;
	}
	void build(int a[]) {
		build(a, 1, 0, len - 1);
		return;
	}
	node pquery(int32_t v, int32_t tl, int32_t tr, int32_t pos) {
		if (tl == tr) {
			return t[v];
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		if (pos <= tm) {
			return pquery((v << 1), tl, tm, pos);
		}
		else {
			return pquery(((v << 1) | 1), tm + 1, tr, pos);
		}
	}
	node pquery(int32_t pos) {
		return pquery(1, 0, len - 1, pos);
	}
	node rquery(int32_t v, int32_t tl, int32_t tr, int32_t l, int32_t r) {
		if (l > tr || r < tl) {
			return zero;
		}
		if (l <= tl && tr <= r) {
			return t[v];
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		node a, b, ans;
		a = rquery((v << 1), tl, tm, l, r);
		b = rquery(((v << 1) | 1), tm + 1, tr, l, r);
		ans.merge(a, b);
		return ans;
	}
	node rquery(int32_t l, int32_t r) {
		return rquery(1, 0, len - 1, l, r);
	}
	void pupd(int32_t v, int32_t tl, int32_t tr, int32_t pos, int val) {
		if (tl == tr) {
			t[v].assign(val);
			return;
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		if (pos <= tm) {
			pupd((v << 1), tl, tm, pos, val);
		}
		else {
			pupd(((v << 1) | 1), tm + 1, tr, pos, val);
		}
		t[v].merge(t[(v << 1)], t[((v << 1) | 1)]);
		return;
	}
	void pupd(int32_t pos, int val) {
		pupd(1, 0, len - 1, pos, val);
		return;
	}
	void rupd(int32_t v, int32_t tl, int32_t tr, int32_t l, int32_t r, int val) {
		if (l > tr || r < tl) {
			return;
		}
		if (l <= tl && tr <= r) {
			apply(v, tl, tr, val);
			return;
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		rupd((v << 1), tl, tm, l, r, val);
		rupd(((v << 1) | 1), tm + 1, tr, l, r, val);
		t[v].merge(t[(v << 1)], t[((v << 1) | 1)]);
		return;
	}
	void rupd(int32_t l, int32_t r, int val) {
		rupd(1, 0, len - 1, l, r, val);
	}

	int find_last_negative(int v, int tl, int tr) {
		if (t[v].val >= 0) {
			return -1;
		}
		if (tl == tr) {
			return tl;
		}
		pushdown(v, tl, tr);
		int tm = (tl + tr) >> 1;
		if (t[(v << 1) | 1].val < 0) {
			return find_last_negative((v << 1) | 1, tm + 1, tr);
		}
		return find_last_negative((v << 1), tl, tm);
	}
	int find_last_negative() {
		return find_last_negative(1, 0, len - 1);
	}
};

SegTree st;

void solve() {
	int n, m;
	cin >> n >> m;

	int a[n], b[m];
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
		st.rupd(0, a[i], -1);
	}

	for (int i = 0; i < m; ++i) {
		cin >> b[i];
		st.rupd(0, b[i], 1);
	}

	int q;
	cin >> q;
	while (q--) {
		int t;
		cin >> t;
		if (t == 1) {
			int i, x;
			cin >> i >> x;
			i--;
			st.rupd(0, a[i], 1);
			a[i] = x;
			st.rupd(0, a[i], -1);
		} else {
			int i, x;
			cin >> i >> x;
			i--;
			st.rupd(0, b[i], -1);
			b[i] = x;
			st.rupd(0, b[i], 1);
		}
		cout << st.find_last_negative() << '\n';
	}

}

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int t = 1;
	// cin >> t;
	while (t--) {
		solve();
		cout << '\n';
	}
	return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1e6 + 1;

int sum[2*maxn],suf[2*maxn];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    pos >>= 1;
    while(pos) {
	sum[pos] = sum[pos << 1] + sum[pos << 1 | 1];
	suf[pos] = min(suf[pos << 1 | 1], sum[pos << 1 | 1] + suf[pos << 1]);
	pos >>= 1;
    }
}

int get() {
    int pos = 1, w = 0;
    if (suf[pos] >= w) {
	return -1;
    }
    while(pos < maxn) {
	if (suf[pos << 1 | 1] < w) {pos = (pos << 1 | 1);}
	else {w -= sum[pos << 1 | 1], pos <<= 1;}
    }
    return pos - maxn;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1e6 + 10;

int sum[maxn<<1],suf[maxn<<1];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    for(pos<<=1;pos;pos<<=1) {
	sum[pos] += x;
	suf[pos] = min(suf[pos<<1|1], sum[pos<<1|1] + suf[pos<<1]);
	pos >>= 1;
    }
}

int get() {
    int pos = 1, w = 0;
    if (suf[pos] >= w) {
	return -1;
    }
    while(pos < maxn) {
	if (suf[pos<<1|1] < w) {pos = pos<<1|1;}
	else {w -= sum[pos<<1|1], pos <<= 1;}
    }
    return pos - maxn;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1 << 20;

int sum[maxn<<1],suf[maxn<<1];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    for(pos>>=1;pos;pos>>=1) {
	sum[pos] += x;
	suf[pos] = min(suf[pos<<1|1], sum[pos<<1|1] + suf[pos<<1]);
    }
}

int get() {
    int pos = 1, w = 0;
    if (suf[pos] >= w) {
	return -1;
    }
    while(pos < maxn) {
	if (suf[pos<<1|1] < w) {pos = pos<<1|1;}
	else {w -= sum[pos<<1|1], pos <<= 1;}
    }
    return pos - maxn;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1e6 + 1;

int sum[2*maxn + 10],suf[2*maxn + 10];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    pos >>= 1;
    while(pos) {
	sum[pos] += x;
	suf[pos] = min(suf[pos << 1 | 1], sum[pos << 1 | 1] + suf[pos << 1]);
	pos >>= 1;
    }
}

int get() {
    ll i = 1;
    if (suf[i] >= 0) {
	return -1;
    }
    while(i < 2 * maxn + 1) {
    	if (suf[i << 1 | 1] >= 0) {
	    i <<= 1;
	} else {
	    i = (i << 1 | 1);
	}
    }
    i >>= 1;
    return i - maxn;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn + 10) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1e6 + 1;

int sum[2*maxn + 10],suf[2*maxn + 10];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    pos >>= 1;
    while(pos) {
	sum[pos] += x;
	suf[pos] = min(suf[pos << 1 | 1], sum[pos << 1 | 1] + suf[pos << 1]);
	pos >>= 1;
    }
}

int get() {
    int pos = 1, w = 0;
    if (suf[pos] >= w) {
	return -1;
    }
    while(pos < maxn) {
	if (suf[pos << 1 | 1] < w) {pos = (pos << 1 | 1);}
	else {w -= sum[pos << 1 | 1], pos <<= 1;}
    }
    return pos - maxn;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn + 10) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1e6 + 1;

int sum[2*maxn + 10],suf[2*maxn + 10];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    pos >>= 1;
    while(pos) {
	sum[pos] += x;
	suf[pos] = min(suf[pos << 1 | 1], sum[pos << 1 | 1] + suf[pos << 1]);
	pos >>= 1;
    }
}

int get() {
    ll pos = 1, w = 0;
    if (suf[pos] >= w) {
	return -1;
    }
    while(pos < maxn) {
	if (suf[pos << 1 | 1] < w) {pos = (pos << 1 | 1);}
	else {w -= sum[pos << 1 | 1], pos <<= 1;}
    }
    return pos - maxn;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn + 10) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1e6 + 10;

int sum[maxn<<1],suf[maxn<<1];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    for(pos>>=1;pos;pos>>=1) {
	sum[pos] += x;
	suf[pos] = min(suf[pos<<1|1], sum[pos<<1|1] + suf[pos<<1]);
    }
}

int get() {
    int pos = 1, w = 0;
    if (suf[pos] >= w) {
	return -1;
    }
    while(pos < maxn) {
	if (suf[pos<<1|1] < w) {pos = pos<<1|1;}
	else {w -= sum[pos<<1|1], pos <<= 1;}
    }
    return pos - maxn;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 3e6;

int sum[maxn<<1],suf[maxn<<1];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    for(pos>>=1;pos;pos>>=1) {
	sum[pos] += x;
	suf[pos] = min(suf[pos<<1|1], sum[pos<<1|1] + suf[pos<<1]);
    }
}

int get() {
    int pos = 1, w = 0;
    if (suf[pos] >= w) {
	return -1;
    }
    while(pos < maxn) {
	if (suf[pos<<1|1] < w) {pos = pos<<1|1;}
	else {w -= sum[pos<<1|1], pos <<= 1;}
    }
    return pos - maxn;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1e6 + 1;

int sum[2*maxn + 10],suf[2*maxn + 10];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    pos >>= 1;
    while(pos) {
	sum[pos] += x;
	suf[pos] = min(suf[pos << 1 | 1], sum[pos << 1 | 1] + suf[pos << 1]);
	pos >>= 1;
    }
}

int get() {
    int pos = 1, w = 0;
    if (suf[pos] >= w) {
	return -1;
    }
    while(pos < maxn) {
	if (suf[pos << 1 | 1] < w) {pos = (pos << 1 | 1);}
	else {w -= sum[pos << 1 | 1], pos <<= 1;}
    }
    return pos;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn + 10) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <vector>
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <ctime>
#include <map>
#include <deque>
#include <cmath>

#define lp(i, s, e) for(int i = s; i < e; ++i)
#define lpi(i, s, e) for(int i = s; i<= e; ++i)
#define ff first
#define ss second
#define pb(x) push_back(x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int maxn = 1e6 + 1;

int sum[2*maxn + 10],suf[2*maxn + 10];
int n;
void update(int pos, int x) {
    pos += maxn;
    sum[pos] += x;
    suf[pos] = sum[pos];
    pos >>= 1;
    while(pos) {
	sum[pos] += x;
	suf[pos] = min(suf[pos << 1 | 1], sum[pos << 1 | 1] + suf[pos << 1]);
	pos >>= 1;
    }
}

int get() {
    int pos = 1, w = 0;
    if (suf[pos] >= w) {
	return -1;
    }
    while(pos < 2 * maxn) {
	if (suf[pos << 1 | 1] < w) {pos = (pos << 1 | 1);}
	else {w -= sum[pos << 1 | 1], pos <<= 1;}
    }
    pos >>= 1;
    return pos - maxn;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    lp(i, 0, 2 * maxn + 10) {sum[i] = suf[i] = 0;}
    cin >> n >> m;
    vector<int> a(n), b(m);
    lp(i, 0, n) {
	cin >> a[i];
	update(a[i], -1);
    }
    lp(i, 0, m) {
	cin >> b[i];
	update(b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
	int t;
	cin >> t;
	if (t == 1) {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(a[i], 1);
	    a[i] = x;
	    update(a[i], -1);
	} else {
	    int i, x;
	    cin >> i >> x;
	    --i;
	    update(b[i], -1);
	    b[i] = x;
	    update(b[i], 1);
	}
	cout << get() << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
using namespace std;

template<typename T>
class AddMax {
  struct Node {
    T x, lazy; // x : max, y : min
    Node() : x(), lazy() {
    }
    void add(T by) {
      x += by;
      lazy += by;
    }
  };
  inline int L(int v) { return v << 1; }
  inline int R(int v) { return L(v) + 1; }

  void push(int v) {
    if(tree[v].lazy) {
      tree[L(v)].add(tree[v].lazy);
      tree[R(v)].add(tree[v].lazy);
      tree[v].lazy = 0;
    }
  }

  int n;
  const T INF;
  vector<Node> tree;

  T maxq(int ql, int qr, int v, int l, int r) {
    if(l > qr || ql > r) return -INF;
    if(ql <= l && r <= qr) return tree[v].x;
    push(v);
    int m = (l + r) >> 1;
    return max(maxq(ql, qr, L(v), l, m), maxq(ql, qr, R(v), m + 1, r));
  }

  void add(int ql, int qr, T by, int v, int l, int r) {
    if(l > qr || ql > r) return;
    if(ql <= l && r <= qr) {
      tree[v].add(by);
    } else {
      push(v);
      int m = (l + r) >> 1;
      add(ql, qr, by, L(v), l, m);
      add(ql, qr, by, R(v), m + 1, r);
      tree[v].x = max(tree[L(v)].x, tree[R(v)].x);
    }
  }

public:
  AddMax(int n_) : n(n_), INF(numeric_limits<T>::max() >> 1) {
    tree.resize(n << 2);
  }
  T maxq(int ql, int qr) { return maxq(ql, qr, 1, 0, n - 1); }
  void add(int ql, int qr, T by) { add(ql, qr, by, 1, 0, n - 1); }
  int max_idx_positive() {
    int l = 0, r = 1000000;
    while(r - l > 1) {
      int m = (l + r) >> 1;
      if(maxq(m + 1, r) > 0) {
        l = m + 1;
      } else {
        r = m;
      }
    }
    if(maxq(r, r) > 0) l = r;
    return (l ? l : -1);
  }
};

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<int> a(n), b(m);
  AddMax<int> am(1000009);

  for(int i = 0; i < n; ++i) {
    cin >> a[i];
    am.add(0, a[i], 1);
  }
  for(int i = 0; i < m; ++i) {
    cin >> b[i];
    am.add(0, b[i], -1);
  }

  int q;
  cin >> q;
  while(q--) {
    int t, i, x;
    cin >> t >> i >> x;
    --i;
    if(t == 1) {
      am.add(0, a[i], -1);
      am.add(0, x, 1);
      a[i] = x;
    } else {
      am.add(0, b[i], 1);
      am.add(0, x, -1);
      b[i] = x;
    }
    cout << am.max_idx_positive() << '\n';
  }
}


#include <bits/stdc++.h>
using namespace std;

template<typename T>
class AddMax {
  struct Node {
    T x, lazy; // x : max, y : min
    Node() : x(), lazy() {
    }
    void add(T by) {
      x += by;
      lazy += by;
    }
  };
  inline int L(int v) { return v << 1; }
  inline int R(int v) { return L(v) + 1; }

  void push(int v) {
    if(tree[v].lazy) {
      tree[L(v)].add(tree[v].lazy);
      tree[R(v)].add(tree[v].lazy);
      tree[v].lazy = 0;
    }
  }

  int n;
  const T INF;
  vector<Node> tree;

  T maxq(int ql, int qr, int v, int l, int r) {
    if(l > qr || ql > r) return -INF;
    if(ql <= l && r <= qr) return tree[v].x;
    push(v);
    int m = (l + r) >> 1;
    return max(maxq(ql, qr, L(v), l, m), maxq(ql, qr, R(v), m + 1, r));
  }

  void add(int ql, int qr, T by, int v, int l, int r) {
    if(l > qr || ql > r) return;
    if(ql <= l && r <= qr) {
      tree[v].add(by);
    } else {
      push(v);
      int m = (l + r) >> 1;
      add(ql, qr, by, L(v), l, m);
      add(ql, qr, by, R(v), m + 1, r);
      tree[v].x = max(tree[L(v)].x, tree[R(v)].x);
    }
  }

public:
  AddMax(int n_) : n(n_), INF(numeric_limits<T>::max() >> 1) {
    tree.resize(n << 2);
  }
  T maxq(int ql, int qr) { return maxq(ql, qr, 1, 0, n - 1); }
  void add(int ql, int qr, T by) { add(ql, qr, by, 1, 0, n - 1); }
  int max_idx_positive() {
    int l = 0, r = 1000000;
    while(r - l > 1) {
      int m = (l + r) >> 1;
      if(maxq(m + 1, r) > 0) {
        l = m + 1;
      } else {
        r = m;
      }
    }
    if(maxq(r, r) > 0) l = r;
    return (l ? l : -1);
  }
};

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<int> a(n), b(m);
  AddMax<int> am(1000009);

  for(int i = 0; i < n; ++i) {
    cin >> a[i];
    am.add(0, a[i], 1);
  }
  for(int i = 0; i < m; ++i) {
    cin >> b[i];
    am.add(0, b[i], -1);
  }

  int q;
  cin >> q;
  while(q--) {
    int t, i, x;
    cin >> t >> i >> x;
    --i;
    if(t == 1) {
      am.add(0, a[i], -1);
      am.add(0, x, 1);
      a[i] = x;
    } else {
      am.add(0, b[i], 1);
      am.add(0, x, -1);
      b[i] = x;
    }
    cout << am.max_idx_positive() << '\n';
  }
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;

struct SegmentTree {
    vector<ll> treeMin, lazy;
    ll n, root, size;
    SegmentTree(int currSize) : n(currSize), root(1) {
        ll x = (ll)(ceil(log2(currSize)));
        size = 2*(ll)pow(2, x);
        treeMin.resize(size, 0);
        lazy.resize(size, 0);
    }
    SegmentTree(const vector<ll> &arr) : n(arr.size()), root(1) {
        ll x = (ll)(ceil(log2(n)));
        size = 2*(ll)pow(2, x);
        treeMin.resize(size);
        lazy.resize(size, 0);
    }
    void pendingUpdate(int node, int start, int end) {
        if(lazy[node]) {
            treeMin[node] += lazy[node];
            if(start != end) {
                lazy[2*node] += lazy[node];
                lazy[2*node+1] += lazy[node];
            }
            lazy[node] = 0;
        }
    }
    void updateRange(int l, int r, ll diff) {updateRange(root, 0, n-1, l, r, diff);}
    void updateRange(int node, int start, int end, int l, int r, ll diff) {
        pendingUpdate(node, start, end);
        if(start > end || start > r || end < l) return;
        if(start >= l && end <= r) {
            treeMin[node] += diff;
            if(start != end) {
                lazy[2*node] += diff;
                lazy[2*node+1] += diff;
            }
            return;
        }
        ll mid = (start + end) / 2;
        updateRange(2*node, start, mid, l, r, diff);
        updateRange(2*node+1, mid+1, end, l, r, diff);
        treeMin[node] = min(treeMin[2*node], treeMin[2*node+1]);
    }
    ll queryMin(int l, int r) {return queryMin(root, 0, n-1, l, r);}
    ll queryMin(int node, int start, int end, int l, int r) {
        if(r < start || end < l) return 1e18;
        pendingUpdate(node, start, end);
        if(l <= start && end <= r) return treeMin[node];
        ll mid = (start+end)/2;
        return min(queryMin(2*node, start, mid, l, r), queryMin(2*node+1, mid+1, end, l, r));
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    SegmentTree st(1e6+10);
    vector<int> a(n);
    multiset<int> vals;
    for(int i = 0; i < n; ++i) {
        cin >> a[i];
        vals.insert(a[i]);
        st.updateRange(1, a[i], -1);
    }
    vector<int> b(m);
    for(int i = 0; i < m; ++i) {
        cin >> b[i];
        st.updateRange(1, b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
        int type, i, x;
        cin >> type >> i >> x;
        --i;
        if(type == 1) {//change price of some dish
            st.updateRange(1, a[i], 1);
            auto it = vals.lower_bound(a[i]);
            assert(it != vals.end());
            vals.erase(it);
            a[i] = x;
            vals.insert(a[i]);
            st.updateRange(1, a[i], -1);
        } else {//change amount of money someone has
            st.updateRange(1, b[i], -1);
            b[i] = x;
            st.updateRange(1, b[i], 1);
        }
        /*
        cout << "seg tree:\n";
        for(int i = 1; i <= 13; ++i) {
            cout << st.queryMin(i, i) << ' ';
        }
        cout << '\n';
        */
        int start = 0, end = 1e6+2, mid;
        if(st.queryMin(1, 1e6+2) >= 0) {
            cout << "-1\n";
            continue;
        }
        while(start+1 < end) {
            mid = start + (end-start)/2;
            int mn = st.queryMin(mid, 1e6+2);
            if(mn < 0) {
                start = mid;
            } else {
                end = mid;
            }
        }
        cout << start << '\n';
    }
}


#include <bits/stdc++.h>
using namespace std;
//#define int long long
//typedef long long ll;

struct SegmentTree {
    vector<int> treeMin, lazy;
    int n, root, size;
    SegmentTree(int currSize) : n(currSize), root(1) {
        int x = (int)(ceil(log2(currSize)));
        size = 2*(int)pow(2, x);
        treeMin.resize(size, 0);
        lazy.resize(size, 0);
    }
    SegmentTree(const vector<int> &arr) : n(arr.size()), root(1) {
        int x = (int)(ceil(log2(n)));
        size = 2*(int)pow(2, x);
        treeMin.resize(size);
        lazy.resize(size, 0);
    }
    void pendingUpdate(int node, int start, int end) {
        if(lazy[node]) {
            treeMin[node] += lazy[node];
            if(start != end) {
                lazy[2*node] += lazy[node];
                lazy[2*node+1] += lazy[node];
            }
            lazy[node] = 0;
        }
    }
    void updateRange(int l, int r, int diff) {updateRange(root, 0, n-1, l, r, diff);}
    void updateRange(int node, int start, int end, int l, int r, int diff) {
        pendingUpdate(node, start, end);
        if(start > end || start > r || end < l) return;
        if(start >= l && end <= r) {
            treeMin[node] += diff;
            if(start != end) {
                lazy[2*node] += diff;
                lazy[2*node+1] += diff;
            }
            return;
        }
        int mid = (start + end) / 2;
        updateRange(2*node, start, mid, l, r, diff);
        updateRange(2*node+1, mid+1, end, l, r, diff);
        treeMin[node] = min(treeMin[2*node], treeMin[2*node+1]);
    }
    int queryMin(int l, int r) {return queryMin(root, 0, n-1, l, r);}
    int queryMin(int node, int start, int end, int l, int r) {
        if(r < start || end < l) return 1e9;
        pendingUpdate(node, start, end);
        if(l <= start && end <= r) return treeMin[node];
        int mid = (start+end)/2;
        return min(queryMin(2*node, start, mid, l, r), queryMin(2*node+1, mid+1, end, l, r));
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    SegmentTree st(1e6+10);
    vector<int> a(n);
    multiset<int> vals;
    for(int i = 0; i < n; ++i) {
        cin >> a[i];
        vals.insert(a[i]);
        st.updateRange(1, a[i], -1);
    }
    vector<int> b(m);
    for(int i = 0; i < m; ++i) {
        cin >> b[i];
        st.updateRange(1, b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
        int type, i, x;
        cin >> type >> i >> x;
        --i;
        if(type == 1) {//change price of some dish
            st.updateRange(1, a[i], 1);
            auto it = vals.lower_bound(a[i]);
            assert(it != vals.end());
            vals.erase(it);
            a[i] = x;
            vals.insert(a[i]);
            st.updateRange(1, a[i], -1);
        } else {//change amount of money someone has
            st.updateRange(1, b[i], -1);
            b[i] = x;
            st.updateRange(1, b[i], 1);
        }
        /*
        cout << "seg tree:\n";
        for(int i = 1; i <= 13; ++i) {
            cout << st.queryMin(i, i) << ' ';
        }
        cout << '\n';
        */
        int start = 0, end = 1e6+2, mid;
        if(st.queryMin(1, 1e6+2) >= 0) {
            cout << "-1\n";
            continue;
        }
        while(start+1 < end) {
            mid = start + (end-start)/2;
            int mn = st.queryMin(mid, 1e6+2);
            if(mn < 0) {
                start = mid;
            } else {
                end = mid;
            }
        }
        cout << start << '\n';
    }
}


#include <bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;

struct SegmentTree {
    vector<ll> treeMin, lazy;
    ll n, root, size;
    SegmentTree(int currSize) : n(currSize), root(1) {
        ll x = (ll)(ceil(log2(currSize)));
        size = 2*(ll)pow(2, x);
        treeMin.resize(size, 0);
        lazy.resize(size, 0);
    }
    SegmentTree(const vector<ll> &arr) : n(arr.size()), root(1) {
        ll x = (ll)(ceil(log2(n)));
        size = 2*(ll)pow(2, x);
        treeMin.resize(size);
        lazy.resize(size, 0);
    }
    void pendingUpdate(int node, int start, int end) {
        if(lazy[node]) {
            treeMin[node] += lazy[node];
            if(start != end) {
                lazy[2*node] += lazy[node];
                lazy[2*node+1] += lazy[node];
            }
            lazy[node] = 0;
        }
    }
    void updateRange(int l, int r, ll diff) {updateRange(root, 0, n-1, l, r, diff);}
    void updateRange(int node, int start, int end, int l, int r, ll diff) {
        pendingUpdate(node, start, end);
        if(start > end || start > r || end < l) return;
        if(start >= l && end <= r) {
            treeMin[node] += diff;
            if(start != end) {
                lazy[2*node] += diff;
                lazy[2*node+1] += diff;
            }
            return;
        }
        ll mid = (start + end) / 2;
        updateRange(2*node, start, mid, l, r, diff);
        updateRange(2*node+1, mid+1, end, l, r, diff);
        treeMin[node] = min(treeMin[2*node], treeMin[2*node+1]);
    }
    ll queryMin(int l, int r) {return queryMin(root, 0, n-1, l, r);}
    ll queryMin(int node, int start, int end, int l, int r) {
        if(r < start || end < l) return 1e9;
        pendingUpdate(node, start, end);
        if(l <= start && end <= r) return treeMin[node];
        ll mid = (start+end)/2;
        return min(queryMin(2*node, start, mid, l, r), queryMin(2*node+1, mid+1, end, l, r));
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    SegmentTree st(1e6+10);
    vector<int> a(n);
    multiset<int> vals;
    for(int i = 0; i < n; ++i) {
        cin >> a[i];
        vals.insert(a[i]);
        st.updateRange(1, a[i], -1);
    }
    vector<int> b(m);
    for(int i = 0; i < m; ++i) {
        cin >> b[i];
        st.updateRange(1, b[i], 1);
    }
    int q;
    cin >> q;
    while(q--) {
        int type, i, x;
        cin >> type >> i >> x;
        --i;
        if(type == 1) {//change price of some dish
            st.updateRange(1, a[i], 1);
            auto it = vals.lower_bound(a[i]);
            assert(it != vals.end());
            vals.erase(it);
            a[i] = x;
            vals.insert(a[i]);
            st.updateRange(1, a[i], -1);
        } else {//change amount of money someone has
            st.updateRange(1, b[i], -1);
            b[i] = x;
            st.updateRange(1, b[i], 1);
        }
        /*
        cout << "seg tree:\n";
        for(int i = 1; i <= 13; ++i) {
            cout << st.queryMin(i, i) << ' ';
        }
        cout << '\n';
        */
        int start = 0, end = 1e6+2, mid;
        if(st.queryMin(1, 1e6+2) >= 0) {
            cout << "-1\n";
            continue;
        }
        while(start+1 < end) {
            mid = start + (end-start)/2;
            int mn = st.queryMin(mid, 1e6+2);
            if(mn < 0) {
                start = mid;
            } else {
                end = mid;
            }
        }
        cout << start << '\n';
    }
}


#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e6;
const int inf = 1e6;

int n, m;
int a[maxn + 5], b[maxn + 5];
int tag[maxn << 2], mx[maxn << 2];

void seta(int p, int d) {
    tag[p] += d;
    mx[p] += d;
}

void push(int p) {
    seta(p + p, tag[p]);
    seta(p + p + 1, tag[p]);
    tag[p] = 0;
}

void modify(int p, int l, int r, int ql, int qr, int d) {
    if (l == ql && r == qr) {
        seta(p, d);
        return ;
    }
    push(p);
    int mid = (l + r) >> 1;
    if (qr <= mid) modify(p + p, l, mid, ql, qr, d);
    else if (mid < ql) modify(p + p + 1, mid + 1, r, ql, qr, d);
    else modify(p + p, l, mid, ql, mid, d), modify(p + p + 1, mid + 1, r, mid + 1, qr, d);
    mx[p] = max(mx[p + p], mx[p + p + 1]);
}

int query(int p, int l, int r) {
    if (l == r) return l;
    push(p);
    int mid = (l + r) >> 1;
    if (mx[p + p + 1] > 0) return query(p + p + 1, mid + 1, r);
    else return query(p + p, l, mid);
}

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        modify(1, 1, inf, 1, a[i], 1);
    }
    for (int i = 1; i <= m; i++) {
        scanf("%d", &b[i]);
        modify(1, 1, inf, 1, b[i], -1);
    }
    int q;
    scanf("%d", &q);
    while (q--) {
        int op, i, x;
        scanf("%d %d %d", &op, &i, &x);
        if (op == 1) {
            modify(1, 1, inf, 1, a[i], -1);
            a[i] = x;
            modify(1, 1, inf, 1, a[i], 1);
        }
        else {
            modify(1, 1, inf, 1, b[i], 1);
            b[i] = x;
            modify(1, 1, inf, 1, b[i], -1);
        }
        if (mx[1] <= 0) printf("%d\n", -1);
        else printf("%d\n", query(1, 1, inf));
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int maxn = 3e5;
const int inf = 1e6;

int n, m;
int a[maxn + 5], b[maxn + 5];
int tag[maxn << 2], mx[maxn << 2];

void seta(int p, int d) {
    tag[p] += d;
    mx[p] += d;
}

void push(int p) {
    seta(p + p, tag[p]);
    seta(p + p + 1, tag[p]);
    tag[p] = 0;
}

void modify(int p, int l, int r, int ql, int qr, int d) {
    if (l == ql && r == qr) {
        seta(p, d);
        return ;
    }
    push(p);
    int mid = (l + r) >> 1;
    if (qr <= mid) modify(p + p, l, mid, ql, qr, d);
    else if (mid < ql) modify(p + p + 1, mid + 1, r, ql, qr, d);
    else modify(p + p, l, mid, ql, mid, d), modify(p + p + 1, mid + 1, r, mid + 1, qr, d);
    mx[p] = max(mx[p + p], mx[p + p + 1]);
}

int query(int p, int l, int r) {
    if (l == r) return l;
    push(p);
    int mid = (l + r) >> 1;
    if (mx[p + p + 1] > 0) return query(p + p + 1, mid + 1, r);
    else return query(p + p, l, mid);
}

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        modify(1, 1, inf, 1, a[i], 1);
    }
    for (int i = 1; i <= m; i++) {
        scanf("%d", &b[i]);
        modify(1, 1, inf, 1, b[i], -1);
    }
    int q;
    scanf("%d", &q);
    while (q--) {
        int op, i, x;
        scanf("%d %d %d", &op, &i, &x);
        if (op == 1) {
            modify(1, 1, inf, 1, a[i], -1);
            a[i] = x;
            modify(1, 1, inf, 1, a[i], 1);
        }
        else {
            modify(1, 1, inf, 1, b[i], 1);
            b[i] = x;
            modify(1, 1, inf, 1, b[i], -1);
        }
        if (mx[1] <= 0) printf("%d\n", -1);
        else printf("%d\n", query(1, 1, inf));
    }
    return 0;
}


#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <cstring>
#include <bitset>
#include <functional>
#include <random>
#include <iomanip>
#define REP(_i,_a,_n) for(int _i=_a;_i<=_n;++_i)
#define PER(_i,_a,_n) for(int _i=_n;_i>=_a;--_i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
//head

const int N = 1e6+10;
const int M = 1e6+10;
int n,m,q,a[N],b[N];
int tr[N<<2],tag[N<<2];
void pd(int o) {
	if (tag[o]) {
		tr[lc]+=tag[o];
		tr[rc]+=tag[o];
		tag[lc]+=tag[o];
		tag[rc]+=tag[o];
		tag[o]=0;
	}
}
void upd(int o, int l, int r, int x, int v) {
	if (r<=x) {
		tr[o]+=v;
		tag[o]+=v;
		return;
	}
	pd(o);
	upd(ls,x,v);
	if (mid<x) upd(rs,x,v);
	tr[o]=max(tr[lc],tr[rc]);
}
int find(int o, int l, int r) {
	if (tr[o]<=0) return -1;
	if (l==r) return l;
	pd(o);
	int t = find(rs);
	return t<0?find(ls):find(rs);
}
int main() {
	scanf("%d%d", &n, &m);
	REP(i,1,n) scanf("%d",a+i),upd(1,1,M,a[i],1);
	REP(i,1,m) scanf("%d",b+i),upd(1,1,M,b[i],-1);
	scanf("%d", &q);
	while (q--) {
		int op,x,y;
		scanf("%d%d%d", &op, &x, &y);
		if (op==1) upd(1,1,M,a[x],-1),a[x]=y,upd(1,1,M,a[x],1);
		else upd(1,1,M,b[x],1),b[x]=y,upd(1,1,M,b[x],-1);
		printf("%d\n", find(1,1,M));
	}
}


#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <cstring>
#include <bitset>
#include <functional>
#include <random>
#include <iomanip>
#define REP(_i,_a,_n) for(int _i=_a;_i<=_n;++_i)
#define PER(_i,_a,_n) for(int _i=_n;_i>=_a;--_i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
//head

const int N = 1e6+10;
const int M = 1e6+10;
int n,m,q,a[N],b[N];
int tr[N<<2],tag[N<<2];
void pd(int o) {
	if (tag[o]) {
		tr[lc]+=tag[o];
		tr[rc]+=tag[o];
		tag[lc]+=tag[o];
		tag[rc]+=tag[o];
		tag[o]=0;
	}
}
void upd(int o, int l, int r, int x, int v) {
	if (r<=x) {
		tr[o]+=v;
		tag[o]+=v;
		return;
	}
	pd(o);
	upd(ls,x,v);
	if (mid<x) upd(rs,x,v);
	tr[o]=max(tr[lc],tr[rc]);
}
int find(int o, int l, int r) {
	if (tr[o]<=0) return -1;
	if (l==r) return l;
	pd(o);
	int t = find(rs);
	return t<0?find(ls):t;
}
int main() {
	scanf("%d%d", &n, &m);
	REP(i,1,n) scanf("%d",a+i),upd(1,1,M,a[i],1);
	REP(i,1,m) scanf("%d",b+i),upd(1,1,M,b[i],-1);
	scanf("%d", &q);
	while (q--) {
		int op,x,y;
		scanf("%d%d%d", &op, &x, &y);
		if (op==1) upd(1,1,M,a[x],-1),a[x]=y,upd(1,1,M,a[x],1);
		else upd(1,1,M,b[x],1),b[x]=y,upd(1,1,M,b[x],-1);
		printf("%d\n", find(1,1,M));
	}
}


/***  بسم الله الرحمن ا لرحيم   ***/
/* MaTb3aa */
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
#include<unordered_map>
#define endl                         '\n'
#define Ceil(x,y)             ((x+y-1)/y)
#define sz(s)               (int)s.size()
#define RT(x)           return cout<<x,0;
#define mem(x,y)    memset(x,y,sizeof(x))
#define all(v) ((v).begin()), ((v).end())
#define test int t;cin>>t;while(t--)
#define Point pair<ll, ll>
#define F first
#define S second
#define watch(x) cout<<#x<<" = { "<<x<<" }\n"
const int dx[] = { 0, -1, 0, 1, 1, 1, -1, -1,0 };
const int dy[] = { 1, 0, -1, 0, 1, -1, 1, -1,0 };
const double PI = acos(-1), EPS = 1e-9;
const int OO = 0x3f3f3f3f, N = 2e6 + 5, mod = 1e9 + 7;
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef unsigned long long ull;
ll gcd(ll x, ll y) { return (!y) ? x : gcd(y, x % y); }
ll lcm(ll x, ll y) { return ((x / gcd(x, y)) * y); }
void file() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
  //  freopen("output.txt", "w", stdout);
#endif  !ONLINEJUDGE
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
}
ll seg[N], lazy[4 * N];
int a[N], b[N];
void check(int n) {
    int l = 2 * n;
    int r = l + 1;
    lazy[l] += lazy[n]; seg[l] += lazy[n];
    lazy[r] += lazy[n]; seg[r] += lazy[n];
    lazy[n] = 0;
}

void update(int n, int s, int e, int x, int y, int val) {
    check(n);
    if (x > e || y < s)return;
    if (s >= x && e <= y) {
        lazy[n] += val;
        seg[n] += val;
        return;
    }
    int mid = s + e >> 1, l = n << 1;
    update(l, s, mid, x, y, val);
    update(l | 1, mid + 1, e, x, y, val);
    seg[n]= max(seg[l], seg[l|1]);
    return;
}
ll solve(int n, int s, int e) {
    if (seg[n] <= 0)return -1;
    if (s == e)
        return e;
    check(n);
    int mid = s + e >> 1, l = n << 1;
    if (seg[l | 1] > 0)
        return solve(l | 1, mid + 1, e);
    return solve(l, s, mid);
}
int main() {
    file();
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        update(1, 1, N, 1, a[i], 1);
    }
    for (int i = 1; i <= m; i++) {
        cin >> b[i];
        update(1, 1, N, 1, b[i], -1);
    }
    int q; cin >> q;
    while (q--) {
        int t, idx, v;
        cin >> t >> idx >> v;
        if (t == 1) {
            update(1, 1, N, 1, a[idx], -1);
            a[idx] = v;
            update(1, 1, N, 1, a[idx], 1);
        }
        else {
            update(1, 1, N, 1, b[idx], 1);
            b[idx] = v;
            update(1, 1, N, 1, b[idx], -1);
        }
        cout << solve(1, 1, N) << endl;
    }

}


/***  بسم الله الرحمن ا لرحيم   ***/
/* MaTb3aa */
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
#include<unordered_map>
#define endl                         '\n'
#define Ceil(x,y)             ((x+y-1)/y)
#define sz(s)               (int)s.size()
#define RT(x)           return cout<<x,0;
#define mem(x,y)    memset(x,y,sizeof(x))
#define all(v) ((v).begin()), ((v).end())
#define test int t;cin>>t;while(t--)
#define Point pair<ll, ll>
#define F first
#define S second
#define watch(x) cout<<#x<<" = { "<<x<<" }\n"
const int dx[] = { 0, -1, 0, 1, 1, 1, -1, -1,0 };
const int dy[] = { 1, 0, -1, 0, 1, -1, 1, -1,0 };
const double PI = acos(-1), EPS = 1e-9;
const int OO = 0x3f3f3f3f, N = 2e6 + 5, mod = 1e9 + 7;
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef unsigned long long ull;
ll gcd(ll x, ll y) { return (!y) ? x : gcd(y, x % y); }
ll lcm(ll x, ll y) { return ((x / gcd(x, y)) * y); }
void file() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
  //  freopen("output.txt", "w", stdout);
#endif  !ONLINEJUDGE
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
}
ll seg[4*N], lazy[4 * N];
int a[N], b[N];
void check(int n) {
    int l = 2 * n;
    int r = l + 1;
    lazy[l] += lazy[n]; seg[l] += lazy[n];
    lazy[r] += lazy[n]; seg[r] += lazy[n];
    lazy[n] = 0;
}

void update(int n, int s, int e, int x, int y, int val) {
    check(n);
    if (x > e || y < s)return;
    if (s >= x && e <= y) {
        lazy[n] += val;
        seg[n] += val;
        return;
    }
    int mid = s + e >> 1, l = n << 1;
    update(l, s, mid, x, y, val);
    update(l | 1, mid + 1, e, x, y, val);
    seg[n]= max(seg[l], seg[l|1]);
    return;
}
ll solve(int n, int s, int e) {
    if (seg[n] <= 0)return -1;
    if (s == e)
        return e;
    check(n);
    int mid = s + e >> 1, l = n << 1;
    if (seg[l | 1] > 0)
        return solve(l | 1, mid + 1, e);
    return solve(l, s, mid);
}
int main() {
    file();
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        update(1, 1, N, 1, a[i], 1);
    }
    for (int i = 1; i <= m; i++) {
        cin >> b[i];
        update(1, 1, N, 1, b[i], -1);
    }
    int q; cin >> q;
    while (q--) {
        int t, idx, v;
        cin >> t >> idx >> v;
        if (t == 1) {
            update(1, 1, N, 1, a[idx], -1);
            a[idx] = v;
            update(1, 1, N, 1, a[idx], 1);
        }
        else {
            update(1, 1, N, 1, b[idx], 1);
            b[idx] = v;
            update(1, 1, N, 1, b[idx], -1);
        }
        cout << solve(1, 1, N) << endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+7;
ll tree[6*N];
ll lazy[6*N];
ll cnt[6*N];

void build(int st, int ed, int nodes)
{
    if(st == ed)
    {
        tree[nodes] = cnt[st];
        return ;
    }

    build(st, (st+ed)/2, 2*nodes);
    build((st+ed)/2 + 1, ed, 2*nodes+1);

    tree[nodes] = max(tree[2*nodes], tree[2*nodes + 1]);
}

void update(int st, int ed, int l, int r, int nodes, int val)
{
    if(lazy[nodes]!=0)
    {
        tree[nodes] += lazy[nodes];
        if(st!=ed)
        {
            lazy[2*nodes] += lazy[nodes];
            lazy[2*nodes+1] += lazy[nodes];
        }
        lazy[nodes] = 0;
    }

    if(st>r || l>ed)
        return ;

    if(st>=l && r>=ed)
    {
        tree[nodes]+=val;
        if(st!=ed)
        {
            lazy[2*nodes] += val;
            lazy[2*nodes+1] += val;
        }
        return ;
    }

    update(st, (st+ed)/2, l, r, 2*nodes, val);
    update((st+ed)/2+1, ed, l, r, 2*nodes+1, val);
    tree[nodes] = max(tree[2*nodes], tree[2*nodes+1]);
}

void push(int st, int ed, int nodes)
{
    if(lazy[nodes]!=0)
    {
        tree[nodes] += lazy[nodes];
        if(st!=ed)
        {
            lazy[2*nodes] += lazy[nodes];
            lazy[2*nodes+1] += lazy[nodes];
        }
        lazy[nodes] = 0;
    }
}

ll query(int st, int ed, int nodes)
{
    push(st, ed, nodes);

    if(st==ed)
    {
        if(tree[nodes]>0) return st;
        else return -1;
    }

    push((st+ed)/2 + 1, ed, 2*nodes + 1);

    if(tree[2*nodes+1]>0)
        return query((st+ed)/2 + 1, ed, 2*nodes+1);
    else
        return query(st, (st+ed)/2, 2*nodes);
}

int main()
{
    int t = 1;
    while(t--)
    {
        ll n, m;
        cin>>n>>m;
        ll a[n+1], b[m+1];
        int maxi = INT_MIN;

        for(int i = 1;i<=n;i++)
        {
            ll x;
            cin>>x;
            a[i] = x;
            cnt[x]++;
            maxi = max(maxi, (int)x);
        }

        for(int i=1;i<=m;i++)
        {
            ll x;
            cin>>x;
            b[i] = x;
            cnt[x]--;
            maxi = max(maxi, (int)x);
        }

        //maxi++;
        maxi = N;
        for(int i = maxi;i>=1;i--)
            cnt[i]+=cnt[i+1];

        //for(int i=1;i<=maxi;i++)
          //  cout<<cnt[i]<<" ";
        //cout<<endl;

        build(1, maxi, 1);
        ll q;
        cin>>q;

        while(q--)
        {
            ll f;
            cin>>f;

            if(f==1)
            {
                ll id, x;
                cin>>id>>x;
                update(1, maxi, 1, a[id], 1, -1);
                a[id] = x;
                update(1, maxi, 1, a[id], 1, 1);
                //for(int i=1;i<=18 ;i++)
                  //  cout<<tree[i]<<" ";
                //cout<<endl;

            }
            else
            {
                ll id, x;
                cin>>id>>x;
                update(1, maxi, 1, b[id], 1, 1);
                b[id] = x;
                update(1, maxi, 1, b[id], 1, -1);

            }
            cout<<query(1, maxi, 1)<<"\n";
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+7;
ll tree[6*N];
ll lazy[6*N];
ll cnt[6*N];

void build(int st, int ed, int nodes)
{
    if(st == ed)
    {
        tree[nodes] = cnt[st];
        return ;
    }

    build(st, (st+ed)/2, 2*nodes);
    build((st+ed)/2 + 1, ed, 2*nodes+1);

    tree[nodes] = max(tree[2*nodes], tree[2*nodes + 1]);
}

void update(int st, int ed, int l, int r, int nodes, int val)
{
    if(lazy[nodes]!=0)
    {
        tree[nodes] += lazy[nodes];
        if(st!=ed)
        {
            lazy[2*nodes] += lazy[nodes];
            lazy[2*nodes+1] += lazy[nodes];
        }
        lazy[nodes] = 0;
    }

    if(st>r || l>ed)
        return ;

    if(st>=l && r>=ed)
    {
        tree[nodes]+=val;
        if(st!=ed)
        {
            lazy[2*nodes] += val;
            lazy[2*nodes+1] += val;
        }
        return ;
    }

    update(st, (st+ed)/2, l, r, 2*nodes, val);
    update((st+ed)/2+1, ed, l, r, 2*nodes+1, val);
    tree[nodes] = max(tree[2*nodes], tree[2*nodes+1]);
}

void push(int st, int ed, int nodes)
{
    if(lazy[nodes]!=0)
    {
        tree[nodes] += lazy[nodes];
        if(st!=ed)
        {
            lazy[2*nodes] += lazy[nodes];
            lazy[2*nodes+1] += lazy[nodes];
        }
        lazy[nodes] = 0;
    }
}

ll query(int st, int ed, int nodes)
{
    push(st, ed, nodes);

    if(st==ed)
    {
        if(tree[nodes]>0) return st;
        else return -1;
    }

    push((st+ed)/2 + 1, ed, 2*nodes + 1);

    if(tree[2*nodes+1]>0)
        return query((st+ed)/2 + 1, ed, 2*nodes+1);
    else
        return query(st, (st+ed)/2, 2*nodes);
}

int main()
{
    int t = 1;
    while(t--)
    {
        ll n, m;
        cin>>n>>m;
        ll a[n+1], b[m+1];
        int maxi = INT_MIN;

        for(int i = 1;i<=n;i++)
        {
            ll x;
            cin>>x;
            a[i] = x;
            cnt[x]++;
            maxi = max(maxi, (int)x);
        }

        for(int i=1;i<=m;i++)
        {
            ll x;
            cin>>x;
            b[i] = x;
            cnt[x]--;
            maxi = max(maxi, (int)x);
        }

        //maxi++;
        maxi = 6*N;
        for(int i = maxi;i>=1;i--)
            cnt[i]+=cnt[i+1];

        //for(int i=1;i<=maxi;i++)
          //  cout<<cnt[i]<<" ";
        //cout<<endl;

        build(1, maxi, 1);
        ll q;
        cin>>q;

        while(q--)
        {
            ll f;
            cin>>f;

            if(f==1)
            {
                ll id, x;
                cin>>id>>x;
                update(1, maxi, 1, a[id], 1, -1);
                a[id] = x;
                update(1, maxi, 1, a[id], 1, 1);
                //for(int i=1;i<=18 ;i++)
                  //  cout<<tree[i]<<" ";
                //cout<<endl;

            }
            else
            {
                ll id, x;
                cin>>id>>x;
                update(1, maxi, 1, b[id], 1, 1);
                b[id] = x;
                update(1, maxi, 1, b[id], 1, -1);

            }
            cout<<query(1, maxi, 1)<<"\n";
        }
    }
}