#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &a) {
  in >> a.first >> a.second;
  return in;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &out, pair<T1, T2> a) {
  out << a.first << " " << a.second;
  return out;
}
template <typename T, typename T1>
T maxs(T &a, T1 b) {
  if (b > a) a = b;
  return a;
}
template <typename T, typename T1>
T mins(T &a, T1 b) {
  if (b < a) a = b;
  return a;
}
const long long N = 1e6 + 5;
struct node {
  long long a = 0;
  node(long long val = 0) { a = val; }
  void merge(node &n1, node &n2) { this->a = max(n1.a, n2.a); }
};
struct update {
  long long val = 0;
  update(long long t = 0) { val = t; }
  void combine(update &par, long long tl, long long tr) { val += par.val; }
  void apply(node &node) {
    node.a += val;
    val = 0;
  }
};
template <typename node, typename update>
struct segtree {
  node t[4 * N];
  bool lazy[4 * N];
  update zaker[4 * N];
  long long tl[4 * N];
  long long tr[4 * N];
  node nul;
  inline void pushdown(long long v) {
    if (lazy[v]) {
      apply(zaker[v], v);
      lazy[v] = 0;
      zaker[v].apply(t[v]);
    }
  }
  inline void apply(update &u, long long v) {
    if (tl[v] != tr[v]) {
      lazy[2 * v] = lazy[2 * v + 1] = 1;
      zaker[2 * v].combine(u, tl[2 * v], tr[2 * v]);
      zaker[2 * v + 1].combine(u, tl[2 * v + 1], tr[2 * v + 1]);
    }
  }
  void build(long long v, long long start, long long end) {
    tl[v] = start;
    tr[v] = end;
    if (start == end) {
      t[v].a = 0;
    } else {
      long long m = (start + end) / 2;
      build(2 * v, start, m);
      build(2 * v + 1, m + 1, end);
      t[v].merge(t[2 * v], t[2 * v + 1]);
    }
  }
  void zeno(long long v, long long l, long long r, update val) {
    pushdown(v);
    if (tr[v] < l || tl[v] > r) return;
    if (l <= tl[v] && tr[v] <= r) {
      t[v].a += val.val;
      apply(val, v);
      return;
    }
    zeno(2 * v, l, r, val);
    zeno(2 * v + 1, l, r, val);
    t[v].merge(t[2 * v], t[2 * v + 1]);
  }
  long long query(long long v) {
    if (t[v].a <= 0) {
      return -1;
    } else {
      while (tl[v] != tr[v]) {
        pushdown(2 * v);
        pushdown(2 * v + 1);
        if (t[2 * v + 1].a > 0) {
          v = 2 * v + 1;
        } else {
          v = 2 * v;
        }
      }
      return tl[v];
    }
  }

 public:
  long long query() { return query(1); }
  void upd(long long l, long long r, update val) { return zeno(1, l, r, val); }
};
segtree<node, update> seg;
const long long M = 1e6;
long long solve() {
  long long n, m;
  cin >> n >> m;
  vector<long long> a(n + 1), b(m + 1);
  seg.build(1, 1, M);
  for (long long i = 1; i < n + 1; i++) {
    cin >> a[i];
    seg.upd(1, a[i], 1);
  }
  for (long long i = 1; i < m + 1; i++) {
    cin >> b[i];
    seg.upd(1, b[i], -1);
  }
  long long q;
  cin >> q;
  for (long long i = 0; i < q; i++) {
    long long t;
    cin >> t;
    long long j, first;
    cin >> j >> first;
    if (t == 1) {
      seg.upd(1, a[j], -1);
      a[j] = first;
      seg.upd(1, a[j], 1);
    } else {
      seg.upd(1, b[j], 1);
      b[j] = first;
      seg.upd(1, b[j], -1);
    }
    cout << seg.query() << "\n";
  }
  return 0;
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long t = 1;
  while (t--) {
    solve();
  }
  return 0;
}
