#include <bits/stdc++.h>
using int_t = long long int;
template <typename T, typename FirstOp = std::plus<T>,
          typename SecondOp = std::multiplies<T>,
          typename UpdateOp = std::plus<T>>
class SegmentTree {
 public:
  explicit SegmentTree(std::size_t size, FirstOp first_operation = FirstOp(),
                       SecondOp second_operation = SecondOp(),
                       UpdateOp update_operation = UpdateOp(), T identity = T())
      : m_size(size),
        m_tree(std::max(size * 4, std::size_t(4)), identity),
        m_lazy_tag(std::max(size * 4, std::size_t(4)), identity),
        m_first_operation(first_operation),
        m_second_operation(second_operation),
        m_update_operation(update_operation),
        m_identity(identity) {}
  void update(std::size_t pos, const T& value) {
    update(pos + 1, value, 1, 1, m_size);
  }
  void update(std::size_t start, std::size_t end, const T& value) {
    update(start + 1, end, value, 1, 1, m_size);
  }
  T query(std::size_t start, std::size_t end) {
    return query(start + 1, end, 1, 1, m_size);
  }

 private:
  std::size_t m_size;
  std::vector<T> m_tree;
  std::vector<T> m_lazy_tag;
  FirstOp m_first_operation;
  SecondOp m_second_operation;
  UpdateOp m_update_operation;
  const T m_identity;
  void push_up(std::size_t root) {
    m_tree[root] = m_first_operation(m_tree[left(root)], m_tree[right(root)]);
  }
  void push_down(std::size_t root, std::size_t length) {
    m_tree[left(root)] = m_update_operation(
        m_tree[left(root)],
        m_second_operation(m_lazy_tag[root], length - length / 2));
    m_lazy_tag[left(root)] =
        m_update_operation(m_lazy_tag[left(root)], m_lazy_tag[root]);
    m_tree[right(root)] = m_update_operation(
        m_tree[right(root)], m_second_operation(m_lazy_tag[root], length / 2));
    m_lazy_tag[right(root)] =
        m_update_operation(m_lazy_tag[right(root)], m_lazy_tag[root]);
    m_lazy_tag[root] = m_identity;
  }
  void update(std::size_t pos, const T& value, std::size_t root, std::size_t l,
              std::size_t r) {
    if (l == r) {
      m_tree[root] = m_update_operation(m_tree[root], value);
      return;
    }
    std::size_t m = (l + r) / 2;
    if (pos <= m) {
      update(pos, value, left(root), l, m);
    } else {
      update(pos, value, right(root), m + 1, r);
    }
    push_up(root);
  }
  void update(std::size_t start, std::size_t end, const T& value,
              std::size_t root, std::size_t l, std::size_t r) {
    if (start <= l && r <= end) {
      m_tree[root] = m_update_operation(m_tree[root],
                                        m_second_operation(value, r - l + 1));
      m_lazy_tag[root] = m_update_operation(m_lazy_tag[root], value);
      return;
    }
    if (m_lazy_tag[root] != m_identity) {
      push_down(root, r - l + 1);
    }
    std::size_t m = (l + r) / 2;
    if (start <= m) {
      update(start, end, value, left(root), l, m);
    }
    if (m < end) {
      update(start, end, value, right(root), m + 1, r);
    }
    push_up(root);
  }
  T query(std::size_t start, std::size_t end, std::size_t root, std::size_t l,
          std::size_t r) {
    if (start <= l && r <= end) {
      return m_tree[root];
    }
    if (m_lazy_tag[root] != m_identity) {
      push_down(root, r - l + 1);
    }
    std::size_t m = (l + r) / 2;
    if (start <= m && m < end) {
      return m_first_operation(query(start, end, left(root), l, m),
                               query(start, end, right(root), m + 1, r));
    } else if (end <= m) {
      return query(start, end, left(root), l, m);
    } else {
      return query(start, end, right(root), m + 1, r);
    }
  }
  static std::size_t left(std::size_t root) { return root * 2; }
  static std::size_t right(std::size_t root) { return root * 2 + 1; }
};
int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int_t m;
  std::cin >> m;
  std::vector<int_t> x(m);
  struct FirstOp {
    int_t operator()(int_t lhs, int_t rhs) const { return std::max(lhs, rhs); }
  };
  struct SecondOp {
    int_t operator()(int_t x, std::size_t) const { return x; }
  };
  SegmentTree<int_t, FirstOp, SecondOp> segment_tree(m);
  for (int_t i = 0; i < m; ++i) {
    int_t p;
    int_t t;
    std::cin >> p >> t;
    int_t index = m - p;
    if (t == 0) {
      segment_tree.update(index, m, -1);
    } else {
      std::cin >> x[index];
      segment_tree.update(index, m, 1);
    }
    if (m == 1) {
      if (segment_tree.query(0, 1) > 0) {
        std::cout << x[0] << '\n';
      } else {
        std::cout << -1 << '\n';
      }
      continue;
    }
    int_t start = 0;
    int_t end = m;
    while (start < end - 1) {
      int_t mid = (start + end - 1) / 2;
      if (segment_tree.query(start, mid + 1) > 0) {
        end = mid + 1;
      } else if (segment_tree.query(mid, end) > 0) {
        start = mid + 1;
      } else {
        start = end = -1;
      }
    }
    if (start == -1) {
      std::cout << -1 << '\n';
    } else {
      std::cout << x[start] << '\n';
    }
  }
  return 0;
}
