# 0: size
# 1-n: elements

init:
    contract.storage[1000] = msg.sender
code:
    # Only owner of the heap is allowed to modify it
    if contract.storage[1000] != msg.sender:
        stop
    # push
    if msg.data[0] == 0:
        sz = contract.storage[0]
        contract.storage[sz + 1] = msg.data[1]
        k = sz + 1
        while k > 1:
            bottom = contract.storage[k]
            top = contract.storage[k/2]
            if bottom < top:
                contract.storage[k] = top
                contract.storage[k/2] = bottom
                k /= 2
            else:
                k = 0
        contract.storage[0] = sz + 1
    # pop
    elif msg.data[0] == 1:
        sz = contract.storage[0]
        if !sz:
            return(0)
        prevtop = contract.storage[1]
        contract.storage[1] = contract.storage[sz]
        contract.storage[sz] = 0
        top = contract.storage[1]
        k = 1
        while k * 2 < sz:
            bottom1 = contract.storage[k * 2]
            bottom2 = contract.storage[k * 2 + 1]
            if bottom1 < top and (bottom1 < bottom2 or k * 2 + 1 >= sz):
                contract.storage[k] = bottom1
                contract.storage[k * 2] = top
                k = k * 2
            elif bottom2 < top and bottom2 < bottom1 and k * 2 + 1 < sz:
                contract.storage[k] = bottom2
                contract.storage[k * 2 + 1] = top
                k = k * 2 + 1
            else:
                k = sz
        contract.storage[0] = sz - 1
        return(prevtop)
    # top
    elif msg.data[0] == 2:
        return(contract.storage[1])
    # size
    elif msg.data[0] == 3:
        return(contract.storage[0])
