
fun main(args:Array<String>):Unit {
    val n = readLine()!!.toInt()
    val minSegmentTree = MinSegmentTree(n)
    val maxSegmentTree = MaxSegmentTree(n)
    readLine()!!.split(' ').map(String::toInt).forEachIndexed{index, i ->
        minSegmentTree[index] = i
        maxSegmentTree[index] = i
    }
    repeat(readLine()!!.toInt()){
        val (c, from, to) = readLine()!!.split(' ').map(String::toInt)
        println(when(c){
            0 -> minSegmentTree[from, to - 1]
            else -> maxSegmentTree[from, to - 1]
        })
    }

}
abstract class SegmentTree<T>(val size:Int, private val mArray:Array<Array<T>>, private val mZero:T){
    protected abstract fun accumulate(a:T, b:T):T
    operator fun set(index:Int, value:T):Unit {
        mArray[0][index] = value
        var pos = index / 2
        for (i in 1 until mArray.size){
            mArray[i][pos] = mArray[i - 1][pos * 2]
            if ((pos * 2 + 1) in mArray[i - 1].indices)
                mArray[i][pos] = accumulate(mArray[i][pos], mArray[i - 1][pos * 2 + 1])
            pos /= 2
        }
    }
    operator fun get(from:Int, to:Int):T{
        var res = mZero
        var left = from
        var right = to
        for (i in 0 until mArray.size){
            if (left % 2 == 1)
                res = accumulate(res, mArray[i][left])
            if (right % 2 == 0)
                res = accumulate(res, mArray[i][right])
            if (left == right) return res
            left = (left + 1) / 2
            right = (right - 1) / 2
            if (left > right) return res
        }
        return res
    }
    companion object {
        inline fun <reified T> Int.to2D(default: T):Array<Array<T>> {
            var size = this
            var count = 1
            while(size != 1){
                ++count
                size = (size + 1) / 2
            }
            val res = Array(count){Array(0){default}}
            size = this
            res[0] = Array(this){default}
            count = 0
            while (size != 1){
                size = (size + 1) / 2
                res[++count] = Array(size){default}
            }
            return res
        }
    }
}
class MaxSegmentTree private constructor (size:Int, array:Array<Array<Int>>):SegmentTree<Int>(size, array, Int.MIN_VALUE){
    companion object {
        operator fun invoke(size:Int):MaxSegmentTree {
            return MaxSegmentTree(size, size.to2D(Int.MIN_VALUE))
        }
    }
    override fun accumulate(a: Int, b: Int): Int {
        return if(a > b) a else b
    }
}

class MinSegmentTree private constructor (size:Int, array:Array<Array<Int>>):SegmentTree<Int>(size, array, Int.MAX_VALUE){
    companion object {
        operator fun invoke(size:Int):MinSegmentTree{
            return MinSegmentTree(size, size.to2D(Int.MAX_VALUE))
        }
    }
    override fun accumulate(a: Int, b: Int): Int {
        return if(a > b) b else a
    }

}

