import Control.Monad
import Control.Monad.ST
import Control.Applicative
import Data.List
import Data.STRef
import qualified Data.Vector.Mutable as MVector

data Operation a = PushBack a | RandomAccess a | PopBack

showOp :: Operation Int -> String
showOp op =
    case op of
    PushBack x -> "PushBack " ++ (show x)
    RandomAccess p -> "RandomAccess " ++ (show p)
    PopBack -> "PopBack"

runOperation :: [Operation Int] -> [Int]
runOperation ops = runST $ do
    idx <- newSTRef 0
    vec <- MVector.new (length ops)
    res <- newSTRef []
    forM_ ops (\op ->
        case op of
        PushBack x -> do
            i <- readSTRef idx
            MVector.write vec i x
            writeSTRef idx (i + 1)
        RandomAccess p -> do
            rs <- readSTRef res
            val <- MVector.read vec p
            writeSTRef res (val : rs)
        PopBack -> do
            i <- readSTRef idx
            writeSTRef idx (i - 1))
    rs <- readSTRef res
    return (reverse rs)

-- reads an Operation, input i is dummy.
readOperation :: Int -> IO (Operation Int)
readOperation i = do
    opStr <- getLine
    let opList = (map read (words opStr)) :: [Int]
    let op = case (head opList) of
                0 -> PushBack (opList !! 1)
                1 -> RandomAccess (opList !! 1)
                _ -> PopBack
    return op

readOperations :: IO [Operation Int]
readOperations = do
    qStr <- getLine
    let q = read qStr :: Int
    ops <- mapM (\i -> readOperation i) [1..q]
    return ops

main = do
    ops <- readOperations
    let res = runOperation ops
    forM_ res print

