class QueueFR:

    def __init__(self):
        self.__back  = None
        self.__front = None
        self.__te = AVLTree()
        self.__td = AVLTree()
        self.__cur_time = 0

    def front(self, time=None):
        if time is None:
            return self.__front

        if self.size(time) == 0:
            return None

        if self.__td.empty():
            return self.__te.get(self.__te.min())

        time = self.__td.floor(time)
        if time is None:
            return self.__te.get(self.__te.select(0))

        d = self.__td.rank(time)
        return self.__te.get(self.__te.select(d + 1))

    def back(self, time=None):
        if time is None:
            return self.__back

        if self.__te.empty():
            return None

        if self.size(time) == 0:
            return None

        time = self.__te.floor(time)
        if time is None:
            return None

        rank = self.__te.rank(time)
        return self.__te.get(self.__te.select(rank))

    def enqueue(self, val, time):
        if val  is None or \
           time is None:
            raise ValueError("Invalid argument of None Type")

        self.__check_time(time)
        if self.__update_time(time):
            self.__back = val
            if self.size() == 0:
                self.__front = self.__back

        self.__te.put(time, val)

    def delete(self, time):
        if time is None:
           raise ValueError("Invalid 'time' argument of None Type")

        if time in self.__te:
            self.__te.delete(time)
        elif time in self.__td:
            self.__td.delete(time)
        else:
            raise ValueError("'time' argument does "
                             "not correspond to any operation")

        self.__back  = self.back(self.__cur_time)
        self.__front = self.front(self.__cur_time)

    def dequeue(self, time):
        self.__check_time(time)

        self.__td.put(time, time)
        d = self.__td.rank(time)
        res = self.__te.get(self.__te.select(d))

        if self.__update_time(time):
            size = self.size()
            if size == 0:
                self.__back = None
                self.__front = None
            elif size == 1:
                self.__front = self.__back
            else:
                self.__front = self.__te.get(self.__te.select(d + 1))
        return res

    def print(self, time=None):
        if time is None:
            time = self.__cur_time

        if self.size(time) == 0:
            return "[]"

        if self.__td.empty() or \
           self.__td.floor(time) is None:
            front_time =  self.__te.min()
        else:
            d = self.__td.rank(self.__td.floor(time))
            front_time = self.__te.select(d + 1)

        rank = self.__te.rank(self.__te.floor(time))
        back_time = self.__te.select(rank)

        return str(self.__te.values(front_time, back_time))

    def size(self, time=None):
        if time is None:
            time = self.__cur_time
        size = self.__te.rank(time) - self.__td.rank(time)
        if time in self.__te:
            size += 1
        elif time in self.__td:
            size -= 1
        if size < 0:
            return 0
        return size

    def __check_time(self, time):
        if time is None:
            raise ValueError("Invalid argument 'time' of None Type")
        if time in self.__te or \
           time in self.__td:
            raise ValueError("Given 'time' is already in use")

    def __update_time(self, time):
        if time >= self.__cur_time:
            self.__cur_time = time
            return True
        return False
class StackFR:

    class Node:

        def __init__(self, type, value):
            self.type  = type
            self.value = value

    def __init__(self):
        self.__top = None

        self.__op  = Tree()

        self.__push = AVLTree()
        self.__pop  = AVLTree()
        self.__cur_time = 0

    def top(self, time=None):
        if time is None or time >= self.__cur_time:
            time = self.__cur_time

        time = self.__op.floor(time)
        if time is None:
            return None

        operation = self.__op[time]
        if operation.type == "PUSH":
            return operation.value

        operation = self.__op.find_bridge_before(time)

        if operation:
            return self.__op[operation].value
        return None

    def push(self, val, time):
        if val  is None or \
           time is None:
            raise ValueError("Invalid argument of None Type")

        self.__check_time(time)

        if self.__update_time(time):
            self.__top = val

        self.__push.put(time, val)
        self.__op.put(time, self.Node("PUSH", val), 1)

    def delete(self, time):
        if time is None:
           raise ValueError("Invalid 'time' argument of None Type")

        self.__op.delete(time)

        if time in self.__push:
            self.__push.delete(time)
        elif time in self.__pop:
            self.__pop.delete(time)
        else:
            raise ValueError("'time' argument does "
                             "not correspond to any operation")

        self.__top  = self.top(self.__cur_time)

    def pop(self, time):
        self.__check_time(time)
        self.__update_time(time)

        self.__op.put(time, self.Node("POP", time), -1)

        self.__pop.put(time, time)

    def size(self, time=None):
        if time is None:
            time = self.__cur_time
        size = self.__push.rank(time) - self.__pop.rank(time)
        if time in self.__push:
            size += 1
        elif time in self.__pop:
            size -= 1
        if size < 0:
            return 0
        return size

    def print(self, time=None):
        if time is None:
            time = self.__cur_time

        if self.size(time) == 0:
            return "[]"

        res = []
        pushes = self.__push.keys_in_order()
        pops   = self.__pop.keys_in_order()

        ipu = 0
        ipo = 0

        if self.__pop.empty():
            for key in pushes:
                if key <= time:
                    res.insert(0, self.__push.get(key))
            return str(res)

        change = True
        while change:
            change = False
            if pushes[ipu] < pops[ipo]:
                res.insert(0, self.__push.get(pushes[ipu]))
                change = True
                if ipu + 1 < len(pushes):
                    ipu += 1

            else:
                res.pop(0)
                change = True
                if ipo + 1 < len(pops):
                    ipo += 1
        return str(res)

    def __check_time(self, time):
        if time is None:
            raise ValueError("Invalid argument 'time' of None Type")
        if time in self.__push or \
           time in self.__pop:
            raise ValueError("Given 'time' is already in use")

    def __update_time(self, time):
        if time >= self.__cur_time:
            self.__cur_time = time
            return True
        return False
class MinPQPR:
    def __init__(self):
        self.__min = None
        self.__cur_time = None
        self.__now = AVLTree()
        self.__insertion = InsertionTree()
        self.__updates = PrefixSumBST()

    def empty(self):
        return self.__min is None

    def size(self):
        return self.__now.size()

    def __len__(self):
        return self.size()

    def min(self):
        return self.__min

    def insert(self, key, time):
        self.__update_time(time)

        if self.__updates.empty():
            self.__now.put(key, time)
            self.__updates.put(time, key, 0)
            self.__insertion.put(time, key, True)
            self.__update_min()
            return

        bridge = self.__updates.find_bridge_before(time)
        bridge = self.__insertion.ceiling(bridge)

        if bridge:
            max_now = self.__insertion.max_right(bridge)
        else:
            max_now = None

        if max_now is None:
            max_k = key
        else:
            max_k = max(max_now.val, key)

        if max_now and max_k == max_now.val:
            self.__updates.put(time, key, 1)
            self.__now.put(max_now.val, max_now.key)
            self.__insertion.put(max_now.key, max_now.val, active=True)
        else:
            self.__insertion.put(time, key, active=True)
            self.__updates.put(time, key, 0)
            self.__now.put(key, time)
        self.__update_min()

    def delete_min(self, time):
        self.__updates.put(time, "delete-min", -1)

        if self.__insertion.empty():
            self.__update_time(time)
            return None

        if self.__update_time(time):
            min_k = self.__min
            min_t = self.__now.get(min_k)

            self.__now.delete_min()
            self.__update_min()

            self.__insertion.put(min_t, min_k, False)

            return min_k

        bridge = self.__updates.find_bridge_after(time)
        bridge = self.__insertion.floor(bridge)

        min_now = self.__insertion.min_left(bridge)

        self.__insertion.put(min_now.key, min_now.val, False)
        self.__now.delete(min_now.val)
        self.__update_min()

        return min_now.val

    def delete(self, time):
        if time is None:
            raise ValueError("Invalid 'time' argument of None Type")
        if time not in self.__updates:
            raise ValueError("'time' argument does "
                             "not correspond to any operation")

        if self.__updates.get(time) == "delete-min":
            bridge = self.__updates.find_bridge_before(time)
            bridge = self.__insertion.ceiling(bridge)

            max_now = self.__insertion.max_right(bridge)

            self.__now.put(max_now.val, max_now.key)
            self.__insertion.put(max_now.key, max_now.val, True)
        else:
            bridge = self.__updates.find_bridge_after(time)
            bridge = self.__insertion.floor(bridge)

            min_now = self.__insertion.min_left(bridge)

            self.__now.delete(min_now.val)
            self.__insertion.delete(min_now.key)

        self.__updates.delete(time)
        self.__update_min()

    def __update_time(self, time):
        if self.__cur_time is None or \
           time >= self.__cur_time:
            self.__cur_time = time
            return True
        return False

    def __update_min(self):
        if self.__now.empty():
            self.__min = None
        else:
            self.__min = self.__now.min()