import Control.Applicative ((<$>))
import Data.List (intersperse)
import Data.Vector.Unboxed (Vector, (!), (//), fromList, toList, thaw, freeze)
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import Control.Monad
import Control.Monad.ST
import Debug.Trace (trace)

main :: IO ()
main = do
    n   <- readLn :: IO Int
    ns  <- fromList . (0 :) . map read . words <$> getLine :: IO (Vector Int)
    let maxHeap = runST $ do
            mns <- VU.thaw ns :: ST s (VUM.MVector s Int)
            forM_ [(n `div` 2), (n `div` 2 - 1)..1] $ \i -> maxHeapify i mns
            freeze mns
    putStrLn . (' ' :) . concat . intersperse " " . map show . tail . toList $ maxHeap


maxHeapify :: Int -> VUM.MVector s Int -> ST s ()
maxHeapify i xs = do
    root  <- VUM.read xs i
    let l    = i * 2
        r    = l + 1
        size = VUM.length xs
    case (size > l, size > r) of
        (True, False) ->
            VUM.read xs l >>= \left -> when (left > root) (VUM.swap xs i l >> maxHeapify l xs)

        (False, True) ->
            VUM.read xs r >>= \right -> when (right > root) (VUM.swap xs i r >> maxHeapify r xs)

        (True, True) ->
            VUM.read xs l >>= \left -> VUM.read xs r >>= \right ->
                if left > right then
                    when (root < left) (VUM.swap xs i l >> maxHeapify l xs)
                else
                    when (root < right) (VUM.swap xs i r >> maxHeapify r xs)
        (False, False) ->
            return ()
