#ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;++i)
#define rrep(i,n) for(int i=n-1;i>=0;--i)
#define reps(i,a,b) for(int i=a;i<b;++i)
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define sz(x) (int)(x).size()
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
using namespace std;
using ll = long long;
using P = pair<int, int>;
template<typename T> inline bool chmax(T &a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T> inline bool chmin(T &a,T b){if(b<a){a=b;return 1;}return 0;}
template<typename T> vector<T> make_vec(size_t a){return vector<T>(a);}
template<typename T,typename... Ts>
auto make_vec(size_t a,Ts... ts){return vector<decltype(make_vec<T>(ts...))>(a,make_vec<T>(ts...));}
template<typename T,typename U,typename... V>
typename enable_if<is_same<T,U>::value>::type fill_v(U &u,const V... v){u=U(v...);}
template<typename T,typename U,typename... V>
typename enable_if<!is_same<T,U>::value>::type fill_v(U &u,const V... v){for(auto &e:u)fill_v<T>(e,v...);}

template <typename T>
struct segment_tree {
    using F = function<T(T, T)>;
    int n;
    vector<T> data;
    T identity;
    F operation;
    segment_tree(T _identity, F _operation)
        : identity(_identity), operation(_operation){}
    void init(int _n) {
        n = 1;
        while (n < _n) n <<= 1;
        data.assign(n<<1, identity);
    }
    void build(const vector<T> &v) {
        int _n = (int)v.size();
        init(_n);
        for (int i = 0; i < _n; ++i) data[n+i] = v[i];
        for (int i = n-1; i >= 0; --i) {
            data[i] = operation(data[i<<1|0], data[i<<1|1]);
        }    
    }
    T operator[](int i) { return data[n+i];}
    void set(int i, T x) {
        i += n;
        data[i] = x;
        while (i > 1) {
            i >>= 1;
            data[i] = operation(data[i<<1|0], data[i<<1|1]);
        }
    }
    T fold(int l, int r) {
        l += n; r += n;
        T resl = identity, resr = identity;
        while (l < r) {
            if (l & 1) resl = operation(resl, data[l++]);
            if (r & 1) resr = operation(data[--r], resr);
            l >>= 1; r >>= 1;
        }
        return operation(resl, resr);
    }
    template <typename C>
    int find(int st, C &check, T &acc, int i, int l, int r) {
        if (l+1 == r) {
            acc = operation(acc, data[i]);
            return check(acc) ? i-n : -1;
        }
        int m = (l+r)>>1;
        if (m <= st) return find(st, check, acc, i<<1|1, m, r);
        if (st <= l && !check(operation(acc, data[i]))) {
            acc = operation(acc, data[i]);
            return -1;
        }
        int vl = find(st, check, acc, i<<1|0, l, m);
        if (vl != -1) return vl;
        return find(st, check, acc, i<<1|1, m, r);
    }
    // min idx s.t. st <= idx && !check(fold(st, idx-1)) && check(fold(st, idx))
    template <typename C>
    int find(int st, C &check) {
        T acc = identity;
        return find(st, check, identity, 1, 0, n);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> a(n);
    rep(i, n) cin >> a[i];
    auto f = [](int a, int b) { return min(a, b);};
    auto g = [](int a, int b) { return max(a, b);};
    const int INF = 1001001001;
    segment_tree<int> segmin(INF, f);
    segment_tree<int> segmax(-INF, g);
    segmin.build(a);
    segmax.build(a);
    int q;
    cin >> q;
    while (q--) {
        int com, b, e;
        cin >> com >> b >> e;
        if (com == 0) {
            cout << segmin.fold(b, e) << endl;
        } else {
            cout << segmax.fold(b, e) << endl;
        }
    }
}



Measured memory_bytes: 3220