data heaps[2^50](owner, size, nodes[2^50](key, value))
data heapIndex

def register():
    i = self.heapIndex
    self.heaps[i].owner = msg.sender
    self.heapIndex = i + 1
    return(i)

def push(heap, key, value):
    assert msg.sender == self.heaps[heap].owner
    sz = self.heaps[heap].size
    self.heaps[heap].nodes[sz].key = key
    self.heaps[heap].nodes[sz].value = value
    k = sz + 1
    while k > 1:
        bottom = self.heaps[heap].nodes[k].key
        top = self.heaps[heap].nodes[k/2].key
        if bottom < top:
            tvalue = self.heaps[heap].nodes[k/2].value
            bvalue = self.heaps[heap].nodes[k].value
            self.heaps[heap].nodes[k].key = top
            self.heaps[heap].nodes[k].value = tvalue
            self.heaps[heap].nodes[k/2].key = bottom
            self.heaps[heap].nodes[k/2].value = bvalue
            k /= 2
        else:
            k = 0
    self.heaps[heap].size = sz + 1

def pop(heap):
    sz = self.heaps[heap].size
    assert sz
    prevtop = self.heaps[heap].nodes[1].value
    self.heaps[heap].nodes[1].key = self.heaps[heap].nodes[sz].key
    self.heaps[heap].nodes[1].value = self.heaps[heap].nodes[sz].value
    self.heaps[heap].nodes[sz].key = 0
    self.heaps[heap].nodes[sz].value = 0
    top = self.heaps[heap].nodes[1].key
    k = 1
    while k * 2 < sz:
        bottom1 = self.heaps[heap].nodes[k * 2].key
        bottom2 = self.heaps[heap].nodes[k * 2 + 1].key
        if bottom1 < top and (bottom1 < bottom2 or k * 2 + 1 >= sz):
            tvalue = self.heaps[heap].nodes[1].value
            bvalue = self.heaps[heap].nodes[k * 2].value
            self.heaps[heap].nodes[k].key = bottom1
            self.heaps[heap].nodes[k].value = bvalue
            self.heaps[heap].nodes[k * 2].key = top
            self.heaps[heap].nodes[k * 2].value = tvalue
            k = k * 2
        elif bottom2 < top and bottom2 < bottom1 and k * 2 + 1 < sz:
            tvalue = self.heaps[heap].nodes[1].value
            bvalue = self.heaps[heap].nodes[k * 2 + 1].value
            self.heaps[heap].nodes[k].key = bottom2
            self.heaps[heap].nodes[k].value = bvalue
            self.heaps[heap].nodes[k * 2 + 1].key = top
            self.heaps[heap].nodes[k * 2 + 1].value = tvalue
            k = k * 2 + 1
        else:
            k = sz
    self.heaps[heap].size = sz - 1
    return(prevtop)

def top(heap):
    return(self.heaps[heap].nodes[1].value)

def size(heap):
    return(self.heaps[heap].size)
