Problem:
Treap

A binary search tree can be unbalanced depending on features of data. For example, if we insert $n$ elements into a binary search tree in ascending order, the tree become a list, leading to long search times. One of strategies is to randomly shuffle the elements to be inserted. However, we should consider to maintain the balanced binary tree where different operations can be performed one by one depending on requirement.

We can maintain the balanced binary search tree by assigning a priority randomly selected to each node and by ordering nodes based on the following properties. Here, we assume that all priorities are distinct and also that all keys are distinct.

binary-search-tree property. If $v$ is a left child of $u$, then $v.key < u.key$ and if $v$ is a right child of $u$, then $u.key < v.key$

heap property. If $v$ is a child of $u$, then $v.priority < u.priority$

This combination of properties is why the tree is called Treap (tree + heap).

An example of Treap is shown in the following figure.

Insert

To insert a new element into a Treap, first of all, insert a node which a randomly selected priority value is assigned in the same way for ordinal binary search tree. For example, the following figure shows the Treap after a node with key = 6 and priority = 90 is inserted.

It is clear that this Treap violates the heap property, so we need to modify the structure of the tree by rotate operations. The rotate operation is to change parent-child relation while maintaing the binary-search-tree property.

The rotate operations can be implemented as follows.

rightRotate(Node t)
Node s = t.left
t.left = s.right
s.right = t
return s // the new root of subtree

leftRotate(Node t)
Node s = t.right
t.right = s.left
s.left = t
return s // the new root of subtree

The following figure shows processes of the rotate operations after the insert operation to maintain the properties.

The insert operation with rotate operations can be implemented as follows.

insert(Node t, int key, int priority) // search the corresponding place recursively
if t == NIL
return Node(key, priority) // create a new node when you reach a leaf
if key == t.key
return t // ignore duplicated keys

if key < t.key // move to the left child
t.left = insert(t.left, key, priority) // update the pointer to the left child
if t.priority < t.left.priority // rotate right if the left child has higher priority
t = rightRotate(t)
else // move to the right child
t.right = insert(t.right, key, priority) // update the pointer to the right child
if t.priority < t.right.priority // rotate left if the right child has higher priority
t = leftRotate(t)

return t

Delete

To delete a node from the Treap, first of all, the target node should be moved until it becomes a leaf by rotate operations. Then, you can remove the node (the leaf). These processes can be implemented as follows.

delete(Node t, int key) // seach the target recursively
if t == NIL
return NIL
if key < t.key // search the target recursively
t.left = delete(t.left, key)
else if key > t.key
t.right = delete(t.right, key)
else
return _delete(t, key)
return t

_delete(Node t, int key) // if t is the target node
if t.left == NIL && t.right == NIL // if t is a leaf
return NIL
else if t.left == NIL // if t has only the right child, then perform left rotate
t = leftRotate(t)
else if t.right == NIL // if t has only the left child, then perform right rotate
t = rightRotate(t)
else // if t has both the left and right child
if t.left.priority > t.right.priority // pull up the child with higher priority
t = rightRotate(t)
else
t = leftRotate(t)
return delete(t, key)

Write a program which performs the following operations to a Treap $T$ based on the above described algorithm.

insert ($k$, $p$): Insert a node containing $k$ as key and $p$ as priority to $T$.

find ($k$): Report whether $T$ has a node containing $k$.

delete ($k$): Delete a node containing $k$.

print(): Print the keys of the binary search tree by inorder tree walk and preorder tree walk respectively.

Input

In the first line, the number of operations $m$ is given. In the following $m$ lines, operations represented by insert $k \; p$, find $k$, delete $k$ or print are given.

Output

For each find($k$) operation, print "yes" if $T$ has a node containing $k$, "no" if not.

In addition, for each print operation, print a list of keys obtained by inorder tree walk and preorder tree walk in a line respectively. Put a space character before each key.

Constraints

The number of operations $ \leq 200,000$

$0 \leq k, p \leq 2,000,000,000$

The height of the binary tree does not exceed 50 if you employ the above algorithm

The keys in the binary search tree are all different.

The priorities in the binary search tree are all different.

The size of output $\leq 10$ MB

Sample Input 1

16
insert 35 99
insert 3 80
insert 1 53
insert 14 25
insert 80 76
insert 42 3
insert 86 47
insert 21 12
insert 7 10
insert 6 90
print
find 21
find 22
delete 35
delete 99
print

Sample Output 1

1 3 6 7 14 21 35 42 80 86
35 6 3 1 14 7 21 80 42 86
yes
no
1 3 6 7 14 21 42 80 86
6 3 1 80 14 7 21 42 86

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Randomized Search Trees, R. Seidel, C.R. Aragon.

Solution in C# (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using SB = System.Text.StringBuilder;
//using System.Text.RegularExpressions;
//using System.Globalization;
//using System.Diagnostics;
using static System.Console;
using System.Numerics;
using static System.Math;
using pair = Pair<int, int>;

class Program
{
    static void Main()
    {
        SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    readonly Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;
    readonly int dom = 998244353;
    bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (b.CompareTo(a) < 0) { a = b; return true; } return false; }

    void solve()
    {
        var S = new TreapSet<int>();
        int Q = cin.nextint;
        for (int i = 0; i < Q; i++)
        {
            var s = cin.next[0];
            if (s == 'i')
            {
                S.Add(cin.nextint, cin.nextint);
            }
            else if (s == 'f')
            {
                int k = cin.nextint;
                if (S.UpperBound(k) - S.LowerBound(k) > 0)
                {
                    WriteLine("yes");
                }
                else
                {
                    WriteLine("no");
                }
            }
            else if (s == 'd')
            {
                S.Remove(cin.nextint);
            }
            else if (s == 'p')
            {
                Write(" "); S.Items(0).join();
                Write(" "); S.Items(1).join();
            }
        }
    }

}

class TreapSet<T>
{
    Node root;
    readonly IComparer<T> comparer;
    readonly Node nil;
    public bool IsMultiSet { get; set; }
    public TreapSet(IComparer<T> comparer)
    {
        nil = new Node(default(T), int.MinValue);
        root = nil;
        this.comparer = comparer;
    }
    public TreapSet(Comparison<T> comaprison) : this(Comparer<T>.Create(comaprison)) { }
    public TreapSet() : this(Comparer<T>.Default) { }
    public bool Add(T v, int u)
    {
        key = v;
        priority = u;
        return insert(ref root);
    }
    public bool Remove(T v)
    {
        key = v;
        return remove(ref root);
    }
    public T this[int index] { get { return find(root, index); } }
    public int Count { get { return root.Count; } }
    public void RemoveAt(int k)
    {
        if (k < 0 || k >= root.Count) throw new ArgumentOutOfRangeException();
        removeAt(ref root, k);
    }
    public T[] Items(int x)
    {
        var ret = new T[root.Count];
        var k = 0;
        if (x == 0) inorder_walk(root, ret, ref k);
        else if (x == 1) preorder_walk(root, ret, ref k);
        return ret;
    }
    void inorder_walk(Node t, T[] a, ref int k)
    {
        if (t.Count == 0) return;
        inorder_walk(t.lst, a, ref k);
        a[k++] = t.Key;
        inorder_walk(t.rst, a, ref k);
    }
    void preorder_walk(Node t, T[] a, ref int k)
    {
        if (t.Count == 0) return;
        a[k++] = t.Key;
        preorder_walk(t.lst, a, ref k);
        inorder_walk(t.rst, a, ref k);
    }

    T key; int priority;
    bool insert(ref Node t)
    {
        if (t.Count == 0) { t = new Node(key, priority); t.lst = t.rst = nil; t.Update(); return true; }
        var cmp = comparer.Compare(t.Key, key);
        bool res;
        if (cmp > 0) // key < t.Key
        {
            res = insert(ref t.lst);
            if(t.Priority < t.lst.Priority) rotR(ref t);
        }
        else if (cmp == 0) // key == t.Key
        {
            if (IsMultiSet) res = insert(ref t.lst);
            else return false;
        }
        else // key > t.key
        {
            res = insert(ref t.rst);
            if (t.Priority < t.rst.Priority) rotL(ref t);
        }

        //balance(ref t);
        t.Update();
        return res;
    }
    bool remove(ref Node t)
    {
        if (t.Count == 0) return false; //該当ノードなし
        var cmp = comparer.Compare(key, t.Key);
        bool ret;
        if (cmp < 0) ret = remove(ref t.lst);
        else if (cmp > 0) ret = remove(ref t.rst);
        else // 削除対象ノード
        {
            if (t.lst.Count == 0 && t.rst.Count == 0)
            {
                t = nil;
                return true;
            }
            else if (t.lst.Count == 0)
            {
                rotL(ref t);
            }
            else if (t.rst.Count == 0)
            {
                rotR(ref t);
            }
            else
            {
                if (t.lst.Priority > t.rst.Priority)
                {
                    rotR(ref t);
                }
                else
                {
                    rotL(ref t);
                }
            }
            ret = remove(ref t);
            //var k = t.lst.Count;
            //if (k == 0)
            //{
            //    t = t.rst;
            //    return true;
            //}
            //if (t.rst.Count == 0) { t = t.lst; return true; }


            //t.Key = find(t.lst, k - 1);
            //removeAt(ref t.lst, k - 1);
        }
        //balance(ref t);
        return ret;
    }
    void removeAt(ref Node t, int k)
    {
        var cnt = t.lst.Count;
        if (cnt < k) removeAt(ref t.rst, k - cnt - 1);
        else if (cnt > k) removeAt(ref t.lst, k);
        else
        {
            if (cnt == 0) { t = t.rst; return; }
            if (t.rst.Count == 0) { t = t.lst; return; }

            t.Key = find(t.lst, k - 1);
            removeAt(ref t.lst, k - 1);
        }
        //balance(ref t);
    }
    //void balance(ref Node t)
    //{
    //    var balance = t.lst.Height - t.rst.Height;
    //    if (balance == -2)
    //    {
    //        if (t.rst.lst.Height - t.rst.rst.Height > 0) { rotR(ref t.rst); }
    //        rotL(ref t);
    //    }
    //    else if (balance == 2)
    //    {
    //        if (t.lst.lst.Height - t.lst.rst.Height < 0) rotL(ref t.lst);
    //        rotR(ref t);
    //    }
    //    else t.Update();
    //}

    T find(Node t, int k)
    {
        if (k < 0 || k > root.Count) throw new ArgumentOutOfRangeException();
        for (; ; )
        {
            if (k == t.lst.Count) return t.Key;
            else if (k < t.lst.Count) t = t.lst;
            else { k -= t.lst.Count + 1; t = t.rst; }
        }
    }
    public int LowerBound(T v)
    {
        var k = 0;
        var t = root;
        for (; ; )
        {
            if (t.Count == 0) return k;
            if (comparer.Compare(v, t.Key) <= 0) t = t.lst;
            else { k += t.lst.Count + 1; t = t.rst; }
        }
    }
    public int UpperBound(T v)
    {
        var k = 0;
        var t = root;
        for (; ; )
        {
            if (t.Count == 0) return k;
            if (comparer.Compare(t.Key, v) <= 0) { k += t.lst.Count + 1; t = t.rst; }
            else t = t.lst;
        }
    }
    void rotR(ref Node t)
    {
        var l = t.lst;
        t.lst = l.rst;
        l.rst = t;
        t.Update();
        l.Update();
        t = l;
    }
    void rotL(ref Node t)
    {
        var r = t.rst;
        t.rst = r.lst;
        r.lst = t;
        t.Update();
        r.Update();
        t = r;
    }

    class Node
    {
        public Node(T key, int priority)
        {
            Key = key;
            Priority = priority;
        }
        public int Count { get; private set; }
        //public sbyte Height { get; private set; }
        public int Priority { get; set; }
        public T Key { get; set; }
        public Node lst, rst;
        public void Update()
        {
            Count = 1 + lst.Count + rst.Count;
            //Height = (sbyte)(1 + Math.Max(lst.Height, rst.Height));
        }
        public override string ToString()
        {
            return string.Format("Count = {0}, Key = {1}", Count, Key);
        }
    }
}

static class Ex
{
    public static void join<T>(this IEnumerable<T> values, string sep = " ") => WriteLine(string.Join(sep, values));
    public static string concat<T>(this IEnumerable<T> values) => string.Concat(values);
    public static string reverse(this string s) { var t = s.ToCharArray(); Array.Reverse(t); return t.concat(); }

    public static int lower_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) < 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
    public static int upper_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) <= 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
}

class Pair<T, U> : IComparable<Pair<T, U>> where T : IComparable<T> where U : IComparable<U>
{
    public T f; public U s;
    public Pair(T f, U s) { this.f = f; this.s = s; }
    public int CompareTo(Pair<T, U> a) => f.CompareTo(a.f) != 0 ? f.CompareTo(a.f) : s.CompareTo(a.s);
    public override string ToString() => $"{f} {s}";
}

class Scanner
{
    string[] s; int i;
    readonly char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan => ReadLine().Split();
    public int[] scanint => Array.ConvertAll(scan, int.Parse);
    public long[] scanlong => Array.ConvertAll(scan, long.Parse);
    public double[] scandouble => Array.ConvertAll(scan, double.Parse);
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint => int.Parse(next);
    public long nextlong => long.Parse(next);
    public double nextdouble => double.Parse(next);
}