#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;   }