#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vll vector<ll>
#define vc vector<char>
#define vs vector<string>
#define vpll vector<pll>
#define vpii vector<pii>
#define umap unordered_map
#define uset unordered_set
#define PQ priority_queue

#define printa(a,L,R) for(int i=L;i<R;i++) cout<<a[i]<<(i==R-1?'\n':' ')
#define printv(a) printa(a,0,a.size())
#define print2d(a,r,c) for(int i=0;i<r;i++) for(int j=0;j<c;j++) cout<<a[i][j]<<(j==c-1?'\n':' ')
#define pb push_back
#define eb emplace_back
#define mt make_tuple
#define fbo find_by_order
#define ook order_of_key
#define MP make_pair
#define UB upper_bound
#define LB lower_bound
#define SQ(x) ((x)*(x))
#define issq(x) (((ll)(sqrt((x))))*((ll)(sqrt((x))))==(x))
#define F first
#define S second
#define mem(a,x) memset(a,x,sizeof(a))
#define inf 1e18
#define E 2.71828182845904523536
#define gamma 0.5772156649
#define nl "\n"
#define lg(r,n) (int)(log2(n)/log2(r))
#define sz(v) (int)v.size()
#define pf printf
#define sf scanf
#define sf1(a)                scanf("%d",&a)
#define sf2(a,b)              scanf("%d %d",&a,&b)
#define sf3(a,b,c)            scanf("%d %d %d",&a,&b,&c)
#define pf1(a)                printf("%d\n",a);
#define pf2(a,b)              printf("%d %d\n",a,b)
#define pf3(a,b,c)            printf("%d %d %d\n",a,b,c)
#define sf1ll(a)              scanf("%lld",&a)
#define sf2ll(a,b)            scanf("%I64d %I64d",&a,&b)
#define sf3ll(a,b,c)          scanf("%I64d %I64d %I64d",&a,&b,&c)
#define pf1ll(a)              printf("%lld\n",a);
#define pf2ll(a,b)            printf("%I64d %I64d\n",a,b)
#define pf3ll(a,b,c)          printf("%I64d %I64d %I64d\n",a,b,c)
#define _ccase printf("Case %lld: ",++cs)
#define _case cout<<"Case "<<++cs<<": "
#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; }

#define asche cerr<<"Ekhane asche\n";
#define rev(v) reverse(v.begin(),v.end())
#define srt(v) sort(v.begin(),v.end())
#define grtsrt(v) sort(v.begin(),v.end(),greater<ll>())
#define all(v) v.begin(),v.end()
#define mnv(v) *min_element(v.begin(),v.end())
#define mxv(v) *max_element(v.begin(),v.end())
#define toint(a) atoi(a.c_str())
#define BeatMeScanf ios_base::sync_with_stdio(false)
#define valid(tx,ty) (tx>=0&&tx<n&&ty>=0&&ty<m)
#define one(x) __builtin_popcount(x)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define stree l=(n<<1),r=l+1,mid=b+(e-b)/2
#define fout(x) fixed<<setprecision(x)
string tostr(int n) {stringstream rr;rr<<n;return rr.str();}
inline void yes(){cout<<"YES\n";exit(0);}
inline void no(){cout<<"NO\n";exit(0);}
template <typename T> using o_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
//ll dx[]={1,0,-1,0,1,-1,-1,1};
//ll dy[]={0,1,0,-1,1,1,-1,-1};
//random_device rd;
//mt19937 rnd(rd());
#define debug(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); deb(_it, args); }
void deb(istream_iterator<string> it) {}
template<typename T, typename... Args>
void deb(istream_iterator<string> it, T a, Args... args) {
    cerr << *it << " = " << a << endl;
    deb(++it, args...);
}

const int mod=1e9+7;
const int N=5e5+9;
const ld eps=1e-9;
const ld PI=acos(-1.0);
//ll gcd(ll a,ll b){while(b){ll x=a%b;a=b;b=x;}return a;}
//ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
//ll qpow(ll n,ll k) {ll ans=1;assert(k>=0);n%=mod;while(k>0){if(k&1) ans=(ans*n)%mod;n=(n*n)%mod;k>>=1;}return ans%mod;}

struct st{
    vi basis;
    int add(int x)
    {
        for(auto &it:basis) if((x^it)<x) x^=it;
        for(auto &it:basis) if((it^x)<it) it^=x;
        if(x){
            basis.eb(x);
            //srt(basis);
        }
    }
    int get()
    {
        int ans=0;
        for(auto x:basis) ans^=x;
        return ans;
    }
    void clear()
    {
        basis.clear();
    }
};
#define SqrtTreeItem st///change for the type you want

st nw;
SqrtTreeItem op(const SqrtTreeItem &a, const SqrtTreeItem &b)
{
    nw.basis=a.basis;
    for(auto x:b.basis) nw.add(x);
    return nw;
    //return a+b;///just change this operation for different problems,no change is required inside the code
}

inline int log2Up(int n) {
    int res = 0;
    while ((1 << res) < n) {
        res++;
    }
    return res;
}
///0-indexed
struct SqrtTree {
    int n, llg, indexSz;
    vector<SqrtTreeItem> v;
    vector<int> clz, layers, onLayer;
    vector< vector<SqrtTreeItem> > pref, suf, between;

    inline void buildBlock(int layer, int l, int r) {
        pref[layer][l] = v[l];
        for (int i = l+1; i < r; i++) {
            pref[layer][i] = op(pref[layer][i-1], v[i]);
        }
        suf[layer][r-1] = v[r-1];
        for (int i = r-2; i >= l; i--) {
            suf[layer][i] = op(v[i], suf[layer][i+1]);
        }
    }

    inline void buildBetween(int layer, int lBound, int rBound, int betweenOffs) {
        int bSzLog = (layers[layer]+1) >> 1;
        int bCntLog = layers[layer] >> 1;
        int bSz = 1 << bSzLog;
        int bCnt = (rBound - lBound + bSz - 1) >> bSzLog;
        for (int i = 0; i < bCnt; i++) {
            SqrtTreeItem ans;
            for (int j = i; j < bCnt; j++) {
                SqrtTreeItem add = suf[layer][lBound + (j << bSzLog)];
                ans = (i == j) ? add : op(ans, add);
                between[layer-1][betweenOffs + lBound + (i << bCntLog) + j] = ans;
            }
        }
    }

    inline void buildBetweenZero() {
        int bSzLog = (llg+1) >> 1;
        for (int i = 0; i < indexSz; i++) {
            v[n+i] = suf[0][i << bSzLog];
        }
        build(1, n, n + indexSz, (1 << llg) - n);
    }

    inline void updateBetweenZero(int bid) {
        int bSzLog = (llg+1) >> 1;
        v[n+bid] = suf[0][bid << bSzLog];
        update(1, n, n + indexSz, (1 << llg) - n, n+bid);
    }

    void build(int layer, int lBound, int rBound, int betweenOffs) {
        if (layer >= (int)layers.size()) {
            return;
        }
        int bSz = 1 << ((layers[layer]+1) >> 1);
        for (int l = lBound; l < rBound; l += bSz) {
            int r = min(l + bSz, rBound);
            buildBlock(layer, l, r);
            build(layer+1, l, r, betweenOffs);
        }
        if (layer == 0) {
            buildBetweenZero();
        } else {
            buildBetween(layer, lBound, rBound, betweenOffs);
        }
    }

    void update(int layer, int lBound, int rBound, int betweenOffs, int x) {
        if (layer >= (int)layers.size()) {
            return;
        }
        int bSzLog = (layers[layer]+1) >> 1;
        int bSz = 1 << bSzLog;
        int blockIdx = (x - lBound) >> bSzLog;
        int l = lBound + (blockIdx << bSzLog);
        int r = min(l + bSz, rBound);
        buildBlock(layer, l, r);
        if (layer == 0) {
            updateBetweenZero(blockIdx);
        } else {
            buildBetween(layer, lBound, rBound, betweenOffs);
        }
        update(layer+1, l, r, betweenOffs, x);
    }

    inline SqrtTreeItem query(int l, int r, int betweenOffs, int base) {
        if (l == r) {
            return v[l];
        }
        if (l + 1 == r) {
            return op(v[l], v[r]);
        }
        int layer = onLayer[clz[(l - base) ^ (r - base)]];
        int bSzLog = (layers[layer]+1) >> 1;
        int bCntLog = layers[layer] >> 1;
        int lBound = (((l - base) >> layers[layer]) << layers[layer]) + base;
        int lBlock = ((l - lBound) >> bSzLog) + 1;
        int rBlock = ((r - lBound) >> bSzLog) - 1;
        SqrtTreeItem ans = suf[layer][l];
        if (lBlock <= rBlock) {
            SqrtTreeItem add = (layer == 0) ? (
                query(n + lBlock, n + rBlock, (1 << llg) - n, n)
            ) : (
                between[layer-1][betweenOffs + lBound + (lBlock << bCntLog) + rBlock]
            );
            ans = op(ans, add);
        }
        ans = op(ans, pref[layer][r]);
        return ans;
    }

    inline SqrtTreeItem query(int l, int r) {
        return query(l, r, 0, 0);
    }

    inline void update(int x, const SqrtTreeItem &item) {
        v[x] = item;
        update(0, 0, n, 0, x);
    }

    SqrtTree(const vector<SqrtTreeItem>& a)
        : n((int)a.size()), llg(log2Up(n)), v(a), clz(1 << llg), onLayer(llg+1) {
        clz[0] = 0;
        for (int i = 1; i < (int)clz.size(); i++) {
            clz[i] = clz[i >> 1] + 1;
        }
        int tllg = llg;
        while (tllg > 1) {
            onLayer[tllg] = (int)layers.size();
            layers.push_back(tllg);
            tllg = (tllg+1) >> 1;
        }
        for (int i = llg-1; i >= 0; i--) {
            onLayer[i] = max(onLayer[i], onLayer[i+1]);
        }
        int betweenLayers = max(0, (int)layers.size() - 1);
        int bSzLog = (llg+1) >> 1;
        int bSz = 1 << bSzLog;
        indexSz = (n + bSz - 1) >> bSzLog;
        v.resize(n + indexSz);
        pref.assign(layers.size(), vector<SqrtTreeItem>(n + indexSz));
        suf.assign(layers.size(), vector<SqrtTreeItem>(n + indexSz));
        between.assign(betweenLayers, vector<SqrtTreeItem>((1 << llg) + bSz));
        build(0, 0, n, 0);
    }
};
int in()
{
    register int c = getchar();
    register int x = 0;
    int neg = 0;
    for(;((c<48 || c>57) && c != '-');c = getchar());
    if(c=='-') {neg=1;c=getchar();}
    for(;c>47 && c<58;c = getchar()) {x = (x<<1) + (x<<3) + c - 48;}
    if(neg) x=-x;
    return x;
}
inline void out(int n)
{
    int N = n<0?-n:n, rev, cnt = 0;
    rev = N;
    if (N == 0) { putchar('0'); putchar('\n'); return ;}
    while ((rev % 10) == 0) { cnt++; rev /= 10;}
    if(n<0) putchar('-');
    rev = 0;
    while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;}
    while (rev != 0) { putchar(rev % 10 + '0'); rev /= 10;}
    while (cnt--) putchar('0');
    putchar('\n');
    return;
}
int main()
{
    //BeatMeScanf;
    //cin.tie(NULL);
    int i,j,k,n,m,l,r,q;
    n=in();
    vector<st>v;
    for(i=1;i<=n;i++){
        k=in();
        st p;
        p.add(k);
        v.eb(p);
    }
    SqrtTree t=SqrtTree(v);
    v.clear();
    q=in();
    st nw;
    while(q--){
        l=in();
        r=in();
        l--;
        r--;
        nw=t.query(l,r);
        int ans=0;
        for(auto x:nw.basis) ans^=x;
        out(ans);
    }
    return 0;
}
///Before submit=>
///    *check for integer overflow,array bounds
///    *check for n=1


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vll vector<ll>
#define vc vector<char>
#define vs vector<string>
#define vpll vector<pll>
#define vpii vector<pii>
#define umap unordered_map
#define uset unordered_set
#define PQ priority_queue

#define printa(a,L,R) for(int i=L;i<R;i++) cout<<a[i]<<(i==R-1?'\n':' ')
#define printv(a) printa(a,0,a.size())
#define print2d(a,r,c) for(int i=0;i<r;i++) for(int j=0;j<c;j++) cout<<a[i][j]<<(j==c-1?'\n':' ')
#define pb push_back
#define eb emplace_back
#define mt make_tuple
#define fbo find_by_order
#define ook order_of_key
#define MP make_pair
#define UB upper_bound
#define LB lower_bound
#define SQ(x) ((x)*(x))
#define issq(x) (((ll)(sqrt((x))))*((ll)(sqrt((x))))==(x))
#define F first
#define S second
#define mem(a,x) memset(a,x,sizeof(a))
#define inf 1e18
#define E 2.71828182845904523536
#define gamma 0.5772156649
#define nl "\n"
#define lg(r,n) (int)(log2(n)/log2(r))
#define sz(v) (int)v.size()
#define pf printf
#define sf scanf
#define sf1(a)                scanf("%d",&a)
#define sf2(a,b)              scanf("%d %d",&a,&b)
#define sf3(a,b,c)            scanf("%d %d %d",&a,&b,&c)
#define pf1(a)                printf("%d\n",a);
#define pf2(a,b)              printf("%d %d\n",a,b)
#define pf3(a,b,c)            printf("%d %d %d\n",a,b,c)
#define sf1ll(a)              scanf("%lld",&a)
#define sf2ll(a,b)            scanf("%I64d %I64d",&a,&b)
#define sf3ll(a,b,c)          scanf("%I64d %I64d %I64d",&a,&b,&c)
#define pf1ll(a)              printf("%lld\n",a);
#define pf2ll(a,b)            printf("%I64d %I64d\n",a,b)
#define pf3ll(a,b,c)          printf("%I64d %I64d %I64d\n",a,b,c)
#define _ccase printf("Case %lld: ",++cs)
#define _case cout<<"Case "<<++cs<<": "
#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; }

#define asche cerr<<"Ekhane asche\n";
#define rev(v) reverse(v.begin(),v.end())
#define srt(v) sort(v.begin(),v.end())
#define grtsrt(v) sort(v.begin(),v.end(),greater<ll>())
#define all(v) v.begin(),v.end()
#define mnv(v) *min_element(v.begin(),v.end())
#define mxv(v) *max_element(v.begin(),v.end())
#define toint(a) atoi(a.c_str())
#define BeatMeScanf ios_base::sync_with_stdio(false)
#define valid(tx,ty) (tx>=0&&tx<n&&ty>=0&&ty<m)
#define one(x) __builtin_popcount(x)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define stree l=(n<<1),r=l+1,mid=b+(e-b)/2
#define fout(x) fixed<<setprecision(x)
string tostr(int n) {stringstream rr;rr<<n;return rr.str();}
inline void yes(){cout<<"YES\n";exit(0);}
inline void no(){cout<<"NO\n";exit(0);}
template <typename T> using o_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
//ll dx[]={1,0,-1,0,1,-1,-1,1};
//ll dy[]={0,1,0,-1,1,1,-1,-1};
//random_device rd;
//mt19937 rnd(rd());
#define debug(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); deb(_it, args); }
void deb(istream_iterator<string> it) {}
template<typename T, typename... Args>
void deb(istream_iterator<string> it, T a, Args... args) {
    cerr << *it << " = " << a << endl;
    deb(++it, args...);
}

const int mod=1e9+7;
const int N=5e5+9;
const ld eps=1e-9;
const ld PI=acos(-1.0);
//ll gcd(ll a,ll b){while(b){ll x=a%b;a=b;b=x;}return a;}
//ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
//ll qpow(ll n,ll k) {ll ans=1;assert(k>=0);n%=mod;while(k>0){if(k&1) ans=(ans*n)%mod;n=(n*n)%mod;k>>=1;}return ans%mod;}

struct st{
    vi basis;
    int add(int x)
    {
        for(auto &it:basis) if((x^it)<x) x^=it;
        for(auto &it:basis) if((it^x)<it) it^=x;
        if(x){
            basis.eb(x);
            srt(basis);
        }
    }
    int get()
    {
        int ans=0;
        for(auto x:basis) ans^=x;
        return ans;
    }
    void clear()
    {
        basis.clear();
    }
};
#define SqrtTreeItem st///change for the type you want

SqrtTreeItem op(const SqrtTreeItem &a, const SqrtTreeItem &b)
{
    st nw;
    nw.basis=a.basis;
    for(auto x:b.basis) nw.add(x);
    return nw;
    //return a+b;///just change this operation for different problems,no change is required inside the code
}

inline int log2Up(int n) {
    int res = 0;
    while ((1 << res) < n) {
        res++;
    }
    return res;
}
///0-indexed
struct SqrtTree {
    int n, llg, indexSz;
    vector<SqrtTreeItem> v;
    vector<int> clz, layers, onLayer;
    vector< vector<SqrtTreeItem> > pref, suf, between;

    inline void buildBlock(int layer, int l, int r) {
        pref[layer][l] = v[l];
        for (int i = l+1; i < r; i++) {
            pref[layer][i] = op(pref[layer][i-1], v[i]);
        }
        suf[layer][r-1] = v[r-1];
        for (int i = r-2; i >= l; i--) {
            suf[layer][i] = op(v[i], suf[layer][i+1]);
        }
    }

    inline void buildBetween(int layer, int lBound, int rBound, int betweenOffs) {
        int bSzLog = (layers[layer]+1) >> 1;
        int bCntLog = layers[layer] >> 1;
        int bSz = 1 << bSzLog;
        int bCnt = (rBound - lBound + bSz - 1) >> bSzLog;
        for (int i = 0; i < bCnt; i++) {
            SqrtTreeItem ans;
            for (int j = i; j < bCnt; j++) {
                SqrtTreeItem add = suf[layer][lBound + (j << bSzLog)];
                ans = (i == j) ? add : op(ans, add);
                between[layer-1][betweenOffs + lBound + (i << bCntLog) + j] = ans;
            }
        }
    }

    inline void buildBetweenZero() {
        int bSzLog = (llg+1) >> 1;
        for (int i = 0; i < indexSz; i++) {
            v[n+i] = suf[0][i << bSzLog];
        }
        build(1, n, n + indexSz, (1 << llg) - n);
    }

    inline void updateBetweenZero(int bid) {
        int bSzLog = (llg+1) >> 1;
        v[n+bid] = suf[0][bid << bSzLog];
        update(1, n, n + indexSz, (1 << llg) - n, n+bid);
    }

    void build(int layer, int lBound, int rBound, int betweenOffs) {
        if (layer >= (int)layers.size()) {
            return;
        }
        int bSz = 1 << ((layers[layer]+1) >> 1);
        for (int l = lBound; l < rBound; l += bSz) {
            int r = min(l + bSz, rBound);
            buildBlock(layer, l, r);
            build(layer+1, l, r, betweenOffs);
        }
        if (layer == 0) {
            buildBetweenZero();
        } else {
            buildBetween(layer, lBound, rBound, betweenOffs);
        }
    }

    void update(int layer, int lBound, int rBound, int betweenOffs, int x) {
        if (layer >= (int)layers.size()) {
            return;
        }
        int bSzLog = (layers[layer]+1) >> 1;
        int bSz = 1 << bSzLog;
        int blockIdx = (x - lBound) >> bSzLog;
        int l = lBound + (blockIdx << bSzLog);
        int r = min(l + bSz, rBound);
        buildBlock(layer, l, r);
        if (layer == 0) {
            updateBetweenZero(blockIdx);
        } else {
            buildBetween(layer, lBound, rBound, betweenOffs);
        }
        update(layer+1, l, r, betweenOffs, x);
    }

    inline SqrtTreeItem query(int l, int r, int betweenOffs, int base) {
        if (l == r) {
            return v[l];
        }
        if (l + 1 == r) {
            return op(v[l], v[r]);
        }
        int layer = onLayer[clz[(l - base) ^ (r - base)]];
        int bSzLog = (layers[layer]+1) >> 1;
        int bCntLog = layers[layer] >> 1;
        int lBound = (((l - base) >> layers[layer]) << layers[layer]) + base;
        int lBlock = ((l - lBound) >> bSzLog) + 1;
        int rBlock = ((r - lBound) >> bSzLog) - 1;
        SqrtTreeItem ans = suf[layer][l];
        if (lBlock <= rBlock) {
            SqrtTreeItem add = (layer == 0) ? (
                query(n + lBlock, n + rBlock, (1 << llg) - n, n)
            ) : (
                between[layer-1][betweenOffs + lBound + (lBlock << bCntLog) + rBlock]
            );
            ans = op(ans, add);
        }
        ans = op(ans, pref[layer][r]);
        return ans;
    }

    inline SqrtTreeItem query(int l, int r) {
        return query(l, r, 0, 0);
    }

    inline void update(int x, const SqrtTreeItem &item) {
        v[x] = item;
        update(0, 0, n, 0, x);
    }

    SqrtTree(const vector<SqrtTreeItem>& a)
        : n((int)a.size()), llg(log2Up(n)), v(a), clz(1 << llg), onLayer(llg+1) {
        clz[0] = 0;
        for (int i = 1; i < (int)clz.size(); i++) {
            clz[i] = clz[i >> 1] + 1;
        }
        int tllg = llg;
        while (tllg > 1) {
            onLayer[tllg] = (int)layers.size();
            layers.push_back(tllg);
            tllg = (tllg+1) >> 1;
        }
        for (int i = llg-1; i >= 0; i--) {
            onLayer[i] = max(onLayer[i], onLayer[i+1]);
        }
        int betweenLayers = max(0, (int)layers.size() - 1);
        int bSzLog = (llg+1) >> 1;
        int bSz = 1 << bSzLog;
        indexSz = (n + bSz - 1) >> bSzLog;
        v.resize(n + indexSz);
        pref.assign(layers.size(), vector<SqrtTreeItem>(n + indexSz));
        suf.assign(layers.size(), vector<SqrtTreeItem>(n + indexSz));
        between.assign(betweenLayers, vector<SqrtTreeItem>((1 << llg) + bSz));
        build(0, 0, n, 0);
    }
};
int in()
{
    register int c = getchar();
    register int x = 0;
    int neg = 0;
    for(;((c<48 || c>57) && c != '-');c = getchar());
    if(c=='-') {neg=1;c=getchar();}
    for(;c>47 && c<58;c = getchar()) {x = (x<<1) + (x<<3) + c - 48;}
    if(neg) x=-x;
    return x;
}
inline void out(int n)
{
    int N = n<0?-n:n, rev, cnt = 0;
    rev = N;
    if (N == 0) { putchar('0'); putchar('\n'); return ;}
    while ((rev % 10) == 0) { cnt++; rev /= 10;}
    if(n<0) putchar('-');
    rev = 0;
    while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;}
    while (rev != 0) { putchar(rev % 10 + '0'); rev /= 10;}
    while (cnt--) putchar('0');
    putchar('\n');
    return;
}
int main()
{
    //BeatMeScanf;
    //cin.tie(NULL);
    int i,j,k,n,m,l,r,q;
    n=in();
    vector<st>v;
    for(i=1;i<=n;i++){
        k=in();
        st p;
        p.add(k);
        v.eb(p);
    }
    SqrtTree t=SqrtTree(v);
    q=in();
    while(q--){
        l=in();
        r=in();
        l--;
        r--;
        st nw=t.query(l,r);
        int ans=0;
        for(auto x:nw.basis) ans^=x;
        out(ans);
    }
    return 0;
}
///Before submit=>
///    *check for integer overflow,array bounds
///    *check for n=1


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vll vector<ll>
#define vc vector<char>
#define vs vector<string>
#define vpll vector<pll>
#define vpii vector<pii>
#define umap unordered_map
#define uset unordered_set
#define PQ priority_queue

#define printa(a,L,R) for(int i=L;i<R;i++) cout<<a[i]<<(i==R-1?'\n':' ')
#define printv(a) printa(a,0,a.size())
#define print2d(a,r,c) for(int i=0;i<r;i++) for(int j=0;j<c;j++) cout<<a[i][j]<<(j==c-1?'\n':' ')
#define pb push_back
#define eb emplace_back
#define mt make_tuple
#define fbo find_by_order
#define ook order_of_key
#define MP make_pair
#define UB upper_bound
#define LB lower_bound
#define SQ(x) ((x)*(x))
#define issq(x) (((ll)(sqrt((x))))*((ll)(sqrt((x))))==(x))
#define F first
#define S second
#define mem(a,x) memset(a,x,sizeof(a))
#define inf 1e18
#define E 2.71828182845904523536
#define gamma 0.5772156649
#define nl "\n"
#define lg(r,n) (int)(log2(n)/log2(r))
#define sz(v) (int)v.size()
#define pf printf
#define sf scanf
#define sf1(a)                scanf("%d",&a)
#define sf2(a,b)              scanf("%d %d",&a,&b)
#define sf3(a,b,c)            scanf("%d %d %d",&a,&b,&c)
#define pf1(a)                printf("%d\n",a);
#define pf2(a,b)              printf("%d %d\n",a,b)
#define pf3(a,b,c)            printf("%d %d %d\n",a,b,c)
#define sf1ll(a)              scanf("%lld",&a)
#define sf2ll(a,b)            scanf("%I64d %I64d",&a,&b)
#define sf3ll(a,b,c)          scanf("%I64d %I64d %I64d",&a,&b,&c)
#define pf1ll(a)              printf("%lld\n",a);
#define pf2ll(a,b)            printf("%I64d %I64d\n",a,b)
#define pf3ll(a,b,c)          printf("%I64d %I64d %I64d\n",a,b,c)
#define _ccase printf("Case %lld: ",++cs)
#define _case cout<<"Case "<<++cs<<": "
#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; }

#define asche cerr<<"Ekhane asche\n";
#define rev(v) reverse(v.begin(),v.end())
#define srt(v) sort(v.begin(),v.end())
#define grtsrt(v) sort(v.begin(),v.end(),greater<ll>())
#define all(v) v.begin(),v.end()
#define mnv(v) *min_element(v.begin(),v.end())
#define mxv(v) *max_element(v.begin(),v.end())
#define toint(a) atoi(a.c_str())
#define BeatMeScanf ios_base::sync_with_stdio(false)
#define valid(tx,ty) (tx>=0&&tx<n&&ty>=0&&ty<m)
#define one(x) __builtin_popcount(x)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define stree l=(n<<1),r=l+1,mid=b+(e-b)/2
#define fout(x) fixed<<setprecision(x)
string tostr(int n) {stringstream rr;rr<<n;return rr.str();}
inline void yes(){cout<<"YES\n";exit(0);}
inline void no(){cout<<"NO\n";exit(0);}
template <typename T> using o_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
//ll dx[]={1,0,-1,0,1,-1,-1,1};
//ll dy[]={0,1,0,-1,1,1,-1,-1};
//random_device rd;
//mt19937 rnd(rd());
#define debug(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); deb(_it, args); }
void deb(istream_iterator<string> it) {}
template<typename T, typename... Args>
void deb(istream_iterator<string> it, T a, Args... args) {
    cerr << *it << " = " << a << endl;
    deb(++it, args...);
}

const int mod=1e9+7;
const int N=5e5+9;
const ld eps=1e-9;
const ld PI=acos(-1.0);
//ll gcd(ll a,ll b){while(b){ll x=a%b;a=b;b=x;}return a;}
//ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
//ll qpow(ll n,ll k) {ll ans=1;assert(k>=0);n%=mod;while(k>0){if(k&1) ans=(ans*n)%mod;n=(n*n)%mod;k>>=1;}return ans%mod;}

struct st{
    vi basis;
    int add(int x)
    {
        for(auto &it:basis) if((x^it)<x) x^=it;
        for(auto &it:basis) if((it^x)<it) it^=x;
        if(x){
            basis.eb(x);
            srt(basis);
        }
    }
    int get()
    {
        int ans=0;
        for(auto x:basis) ans^=x;
        return ans;
    }
    void clear()
    {
        basis.clear();
    }
};
#define SqrtTreeItem st///change for the type you want

SqrtTreeItem op(const SqrtTreeItem &a, const SqrtTreeItem &b)
{
    st nw;
    nw.basis=a.basis;
    for(auto x:b.basis) nw.add(x);
    return nw;
    //return a+b;///just change this operation for different problems,no change is required inside the code
}

inline int log2Up(int n) {
    int res = 0;
    while ((1 << res) < n) {
        res++;
    }
    return res;
}
///0-indexed
struct SqrtTree {
    int n, llg, indexSz;
    vector<SqrtTreeItem> v;
    vector<int> clz, layers, onLayer;
    vector< vector<SqrtTreeItem> > pref, suf, between;

    inline void buildBlock(int layer, int l, int r) {
        pref[layer][l] = v[l];
        for (int i = l+1; i < r; i++) {
            pref[layer][i] = op(pref[layer][i-1], v[i]);
        }
        suf[layer][r-1] = v[r-1];
        for (int i = r-2; i >= l; i--) {
            suf[layer][i] = op(v[i], suf[layer][i+1]);
        }
    }

    inline void buildBetween(int layer, int lBound, int rBound, int betweenOffs) {
        int bSzLog = (layers[layer]+1) >> 1;
        int bCntLog = layers[layer] >> 1;
        int bSz = 1 << bSzLog;
        int bCnt = (rBound - lBound + bSz - 1) >> bSzLog;
        for (int i = 0; i < bCnt; i++) {
            SqrtTreeItem ans;
            for (int j = i; j < bCnt; j++) {
                SqrtTreeItem add = suf[layer][lBound + (j << bSzLog)];
                ans = (i == j) ? add : op(ans, add);
                between[layer-1][betweenOffs + lBound + (i << bCntLog) + j] = ans;
            }
        }
    }

    inline void buildBetweenZero() {
        int bSzLog = (llg+1) >> 1;
        for (int i = 0; i < indexSz; i++) {
            v[n+i] = suf[0][i << bSzLog];
        }
        build(1, n, n + indexSz, (1 << llg) - n);
    }

    inline void updateBetweenZero(int bid) {
        int bSzLog = (llg+1) >> 1;
        v[n+bid] = suf[0][bid << bSzLog];
        update(1, n, n + indexSz, (1 << llg) - n, n+bid);
    }

    void build(int layer, int lBound, int rBound, int betweenOffs) {
        if (layer >= (int)layers.size()) {
            return;
        }
        int bSz = 1 << ((layers[layer]+1) >> 1);
        for (int l = lBound; l < rBound; l += bSz) {
            int r = min(l + bSz, rBound);
            buildBlock(layer, l, r);
            build(layer+1, l, r, betweenOffs);
        }
        if (layer == 0) {
            buildBetweenZero();
        } else {
            buildBetween(layer, lBound, rBound, betweenOffs);
        }
    }

    void update(int layer, int lBound, int rBound, int betweenOffs, int x) {
        if (layer >= (int)layers.size()) {
            return;
        }
        int bSzLog = (layers[layer]+1) >> 1;
        int bSz = 1 << bSzLog;
        int blockIdx = (x - lBound) >> bSzLog;
        int l = lBound + (blockIdx << bSzLog);
        int r = min(l + bSz, rBound);
        buildBlock(layer, l, r);
        if (layer == 0) {
            updateBetweenZero(blockIdx);
        } else {
            buildBetween(layer, lBound, rBound, betweenOffs);
        }
        update(layer+1, l, r, betweenOffs, x);
    }

    inline SqrtTreeItem query(int l, int r, int betweenOffs, int base) {
        if (l == r) {
            return v[l];
        }
        if (l + 1 == r) {
            return op(v[l], v[r]);
        }
        int layer = onLayer[clz[(l - base) ^ (r - base)]];
        int bSzLog = (layers[layer]+1) >> 1;
        int bCntLog = layers[layer] >> 1;
        int lBound = (((l - base) >> layers[layer]) << layers[layer]) + base;
        int lBlock = ((l - lBound) >> bSzLog) + 1;
        int rBlock = ((r - lBound) >> bSzLog) - 1;
        SqrtTreeItem ans = suf[layer][l];
        if (lBlock <= rBlock) {
            SqrtTreeItem add = (layer == 0) ? (
                query(n + lBlock, n + rBlock, (1 << llg) - n, n)
            ) : (
                between[layer-1][betweenOffs + lBound + (lBlock << bCntLog) + rBlock]
            );
            ans = op(ans, add);
        }
        ans = op(ans, pref[layer][r]);
        return ans;
    }

    inline SqrtTreeItem query(int l, int r) {
        return query(l, r, 0, 0);
    }

    inline void update(int x, const SqrtTreeItem &item) {
        v[x] = item;
        update(0, 0, n, 0, x);
    }

    SqrtTree(const vector<SqrtTreeItem>& a)
        : n((int)a.size()), llg(log2Up(n)), v(a), clz(1 << llg), onLayer(llg+1) {
        clz[0] = 0;
        for (int i = 1; i < (int)clz.size(); i++) {
            clz[i] = clz[i >> 1] + 1;
        }
        int tllg = llg;
        while (tllg > 1) {
            onLayer[tllg] = (int)layers.size();
            layers.push_back(tllg);
            tllg = (tllg+1) >> 1;
        }
        for (int i = llg-1; i >= 0; i--) {
            onLayer[i] = max(onLayer[i], onLayer[i+1]);
        }
        int betweenLayers = max(0, (int)layers.size() - 1);
        int bSzLog = (llg+1) >> 1;
        int bSz = 1 << bSzLog;
        indexSz = (n + bSz - 1) >> bSzLog;
        v.resize(n + indexSz);
        pref.assign(layers.size(), vector<SqrtTreeItem>(n + indexSz));
        suf.assign(layers.size(), vector<SqrtTreeItem>(n + indexSz));
        between.assign(betweenLayers, vector<SqrtTreeItem>((1 << llg) + bSz));
        build(0, 0, n, 0);
    }
};
int in()
{
    register int c = getchar();
    register int x = 0;
    int neg = 0;
    for(;((c<48 || c>57) && c != '-');c = getchar());
    if(c=='-') {neg=1;c=getchar();}
    for(;c>47 && c<58;c = getchar()) {x = (x<<1) + (x<<3) + c - 48;}
    if(neg) x=-x;
    return x;
}
inline void out(int n)
{
    int N = n<0?-n:n, rev, cnt = 0;
    rev = N;
    if (N == 0) { putchar('0'); putchar('\n'); return ;}
    while ((rev % 10) == 0) { cnt++; rev /= 10;}
    if(n<0) putchar('-');
    rev = 0;
    while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;}
    while (rev != 0) { putchar(rev % 10 + '0'); rev /= 10;}
    while (cnt--) putchar('0');
    putchar('\n');
    return;
}
int main()
{
    //BeatMeScanf;
    //cin.tie(NULL);
    int i,j,k,n,m,l,r,q;
    n=in();
    vector<st>v;
    for(i=1;i<=n;i++){
        k=in();
        st p;
        p.add(k);
        v.eb(p);
    }
    SqrtTree t=SqrtTree(v);
    v.clear();
    q=in();
    st nw;
    while(q--){
        l=in();
        r=in();
        l--;
        r--;
        nw=t.query(l,r);
        int ans=0;
        for(auto x:nw.basis) ans^=x;
        out(ans);
    }
    return 0;
}
///Before submit=>
///    *check for integer overflow,array bounds
///    *check for n=1


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vll vector<ll>
#define vc vector<char>
#define vs vector<string>
#define vpll vector<pll>
#define vpii vector<pii>
#define umap unordered_map
#define uset unordered_set
#define PQ priority_queue

#define printa(a,L,R) for(int i=L;i<R;i++) cout<<a[i]<<(i==R-1?'\n':' ')
#define printv(a) printa(a,0,a.size())
#define print2d(a,r,c) for(int i=0;i<r;i++) for(int j=0;j<c;j++) cout<<a[i][j]<<(j==c-1?'\n':' ')
#define pb push_back
#define eb emplace_back
#define mt make_tuple
#define fbo find_by_order
#define ook order_of_key
#define MP make_pair
#define UB upper_bound
#define LB lower_bound
#define SQ(x) ((x)*(x))
#define issq(x) (((ll)(sqrt((x))))*((ll)(sqrt((x))))==(x))
#define F first
#define S second
#define mem(a,x) memset(a,x,sizeof(a))
#define inf 1e18
#define E 2.71828182845904523536
#define gamma 0.5772156649
#define nl "\n"
#define lg(r,n) (int)(log2(n)/log2(r))
#define sz(v) (int)v.size()
#define pf printf
#define sf scanf
#define sf1(a)                scanf("%d",&a)
#define sf2(a,b)              scanf("%d %d",&a,&b)
#define sf3(a,b,c)            scanf("%d %d %d",&a,&b,&c)
#define pf1(a)                printf("%d\n",a);
#define pf2(a,b)              printf("%d %d\n",a,b)
#define pf3(a,b,c)            printf("%d %d %d\n",a,b,c)
#define sf1ll(a)              scanf("%lld",&a)
#define sf2ll(a,b)            scanf("%I64d %I64d",&a,&b)
#define sf3ll(a,b,c)          scanf("%I64d %I64d %I64d",&a,&b,&c)
#define pf1ll(a)              printf("%lld\n",a);
#define pf2ll(a,b)            printf("%I64d %I64d\n",a,b)
#define pf3ll(a,b,c)          printf("%I64d %I64d %I64d\n",a,b,c)
#define _ccase printf("Case %lld: ",++cs)
#define _case cout<<"Case "<<++cs<<": "
#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; }

#define asche cerr<<"Ekhane asche\n";
#define rev(v) reverse(v.begin(),v.end())
#define srt(v) sort(v.begin(),v.end())
#define grtsrt(v) sort(v.begin(),v.end(),greater<ll>())
#define all(v) v.begin(),v.end()
#define mnv(v) *min_element(v.begin(),v.end())
#define mxv(v) *max_element(v.begin(),v.end())
#define toint(a) atoi(a.c_str())
#define BeatMeScanf ios_base::sync_with_stdio(false)
#define valid(tx,ty) (tx>=0&&tx<n&&ty>=0&&ty<m)
#define one(x) __builtin_popcount(x)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define stree l=(n<<1),r=l+1,mid=b+(e-b)/2
#define fout(x) fixed<<setprecision(x)
string tostr(int n) {stringstream rr;rr<<n;return rr.str();}
inline void yes(){cout<<"YES\n";exit(0);}
inline void no(){cout<<"NO\n";exit(0);}
template <typename T> using o_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
//ll dx[]={1,0,-1,0,1,-1,-1,1};
//ll dy[]={0,1,0,-1,1,1,-1,-1};
//random_device rd;
//mt19937 rnd(rd());
#define debug(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); deb(_it, args); }
void deb(istream_iterator<string> it) {}
template<typename T, typename... Args>
void deb(istream_iterator<string> it, T a, Args... args) {
    cerr << *it << " = " << a << endl;
    deb(++it, args...);
}

const int mod=1e9+7;
const int N=5e5+9;
const ld eps=1e-9;
const ld PI=acos(-1.0);
//ll gcd(ll a,ll b){while(b){ll x=a%b;a=b;b=x;}return a;}
//ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
//ll qpow(ll n,ll k) {ll ans=1;assert(k>=0);n%=mod;while(k>0){if(k&1) ans=(ans*n)%mod;n=(n*n)%mod;k>>=1;}return ans%mod;}

struct st{
    vi basis;
    int add(int x)
    {
        for(auto &it:basis) if((x^it)<x) x^=it;
        for(auto &it:basis) if((it^x)<it) it^=x;
        if(x){
            basis.eb(x);
            //srt(basis);
        }
    }
    int get()
    {
        int ans=0;
        for(auto x:basis) ans^=x;
        return ans;
    }
    void clear()
    {
        basis.clear();
    }
};
#define SqrtTreeItem st///change for the type you want

SqrtTreeItem op(const SqrtTreeItem &a, const SqrtTreeItem &b)
{
    st nw;
    nw.basis=a.basis;
    for(auto x:b.basis) nw.add(x);
    return nw;
    //return a+b;///just change this operation for different problems,no change is required inside the code
}

inline int log2Up(int n) {
    int res = 0;
    while ((1 << res) < n) {
        res++;
    }
    return res;
}
///0-indexed
struct SqrtTree {
    int n, llg, indexSz;
    vector<SqrtTreeItem> v;
    vector<int> clz, layers, onLayer;
    vector< vector<SqrtTreeItem> > pref, suf, between;

    inline void buildBlock(int layer, int l, int r) {
        pref[layer][l] = v[l];
        for (int i = l+1; i < r; i++) {
            pref[layer][i] = op(pref[layer][i-1], v[i]);
        }
        suf[layer][r-1] = v[r-1];
        for (int i = r-2; i >= l; i--) {
            suf[layer][i] = op(v[i], suf[layer][i+1]);
        }
    }

    inline void buildBetween(int layer, int lBound, int rBound, int betweenOffs) {
        int bSzLog = (layers[layer]+1) >> 1;
        int bCntLog = layers[layer] >> 1;
        int bSz = 1 << bSzLog;
        int bCnt = (rBound - lBound + bSz - 1) >> bSzLog;
        for (int i = 0; i < bCnt; i++) {
            SqrtTreeItem ans;
            for (int j = i; j < bCnt; j++) {
                SqrtTreeItem add = suf[layer][lBound + (j << bSzLog)];
                ans = (i == j) ? add : op(ans, add);
                between[layer-1][betweenOffs + lBound + (i << bCntLog) + j] = ans;
            }
        }
    }

    inline void buildBetweenZero() {
        int bSzLog = (llg+1) >> 1;
        for (int i = 0; i < indexSz; i++) {
            v[n+i] = suf[0][i << bSzLog];
        }
        build(1, n, n + indexSz, (1 << llg) - n);
    }

    inline void updateBetweenZero(int bid) {
        int bSzLog = (llg+1) >> 1;
        v[n+bid] = suf[0][bid << bSzLog];
        update(1, n, n + indexSz, (1 << llg) - n, n+bid);
    }

    void build(int layer, int lBound, int rBound, int betweenOffs) {
        if (layer >= (int)layers.size()) {
            return;
        }
        int bSz = 1 << ((layers[layer]+1) >> 1);
        for (int l = lBound; l < rBound; l += bSz) {
            int r = min(l + bSz, rBound);
            buildBlock(layer, l, r);
            build(layer+1, l, r, betweenOffs);
        }
        if (layer == 0) {
            buildBetweenZero();
        } else {
            buildBetween(layer, lBound, rBound, betweenOffs);
        }
    }

    void update(int layer, int lBound, int rBound, int betweenOffs, int x) {
        if (layer >= (int)layers.size()) {
            return;
        }
        int bSzLog = (layers[layer]+1) >> 1;
        int bSz = 1 << bSzLog;
        int blockIdx = (x - lBound) >> bSzLog;
        int l = lBound + (blockIdx << bSzLog);
        int r = min(l + bSz, rBound);
        buildBlock(layer, l, r);
        if (layer == 0) {
            updateBetweenZero(blockIdx);
        } else {
            buildBetween(layer, lBound, rBound, betweenOffs);
        }
        update(layer+1, l, r, betweenOffs, x);
    }

    inline SqrtTreeItem query(int l, int r, int betweenOffs, int base) {
        if (l == r) {
            return v[l];
        }
        if (l + 1 == r) {
            return op(v[l], v[r]);
        }
        int layer = onLayer[clz[(l - base) ^ (r - base)]];
        int bSzLog = (layers[layer]+1) >> 1;
        int bCntLog = layers[layer] >> 1;
        int lBound = (((l - base) >> layers[layer]) << layers[layer]) + base;
        int lBlock = ((l - lBound) >> bSzLog) + 1;
        int rBlock = ((r - lBound) >> bSzLog) - 1;
        SqrtTreeItem ans = suf[layer][l];
        if (lBlock <= rBlock) {
            SqrtTreeItem add = (layer == 0) ? (
                query(n + lBlock, n + rBlock, (1 << llg) - n, n)
            ) : (
                between[layer-1][betweenOffs + lBound + (lBlock << bCntLog) + rBlock]
            );
            ans = op(ans, add);
        }
        ans = op(ans, pref[layer][r]);
        return ans;
    }

    inline SqrtTreeItem query(int l, int r) {
        return query(l, r, 0, 0);
    }

    inline void update(int x, const SqrtTreeItem &item) {
        v[x] = item;
        update(0, 0, n, 0, x);
    }

    SqrtTree(const vector<SqrtTreeItem>& a)
        : n((int)a.size()), llg(log2Up(n)), v(a), clz(1 << llg), onLayer(llg+1) {
        clz[0] = 0;
        for (int i = 1; i < (int)clz.size(); i++) {
            clz[i] = clz[i >> 1] + 1;
        }
        int tllg = llg;
        while (tllg > 1) {
            onLayer[tllg] = (int)layers.size();
            layers.push_back(tllg);
            tllg = (tllg+1) >> 1;
        }
        for (int i = llg-1; i >= 0; i--) {
            onLayer[i] = max(onLayer[i], onLayer[i+1]);
        }
        int betweenLayers = max(0, (int)layers.size() - 1);
        int bSzLog = (llg+1) >> 1;
        int bSz = 1 << bSzLog;
        indexSz = (n + bSz - 1) >> bSzLog;
        v.resize(n + indexSz);
        pref.assign(layers.size(), vector<SqrtTreeItem>(n + indexSz));
        suf.assign(layers.size(), vector<SqrtTreeItem>(n + indexSz));
        between.assign(betweenLayers, vector<SqrtTreeItem>((1 << llg) + bSz));
        build(0, 0, n, 0);
    }
};
int in()
{
    register int c = getchar();
    register int x = 0;
    int neg = 0;
    for(;((c<48 || c>57) && c != '-');c = getchar());
    if(c=='-') {neg=1;c=getchar();}
    for(;c>47 && c<58;c = getchar()) {x = (x<<1) + (x<<3) + c - 48;}
    if(neg) x=-x;
    return x;
}
inline void out(int n)
{
    int N = n<0?-n:n, rev, cnt = 0;
    rev = N;
    if (N == 0) { putchar('0'); putchar('\n'); return ;}
    while ((rev % 10) == 0) { cnt++; rev /= 10;}
    if(n<0) putchar('-');
    rev = 0;
    while (N != 0) { rev = (rev<<3) + (rev<<1) + N % 10; N /= 10;}
    while (rev != 0) { putchar(rev % 10 + '0'); rev /= 10;}
    while (cnt--) putchar('0');
    putchar('\n');
    return;
}
int main()
{
    //BeatMeScanf;
    //cin.tie(NULL);
    int i,j,k,n,m,l,r,q;
    n=in();
    vector<st>v;
    for(i=1;i<=n;i++){
        k=in();
        st p;
        p.add(k);
        v.eb(p);
    }
    SqrtTree t=SqrtTree(v);
    v.clear();
    q=in();
    st nw;
    while(q--){
        l=in();
        r=in();
        l--;
        r--;
        nw=t.query(l,r);
        int ans=0;
        for(auto x:nw.basis) ans^=x;
        out(ans);
    }
    return 0;
}
///Before submit=>
///    *check for integer overflow,array bounds
///    *check for n=1


#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
const int max_base = 20;
int n, q, l, r;
int a[maxn], val[max_base+3], pos[max_base+3], ans[maxn];
vector<pair<int, int> > R[1000005];//R[i]存右边界为i的区间，key表示左边界，value表示对应的编号
int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    scanf("%d",&n);
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    scanf("%d",&q);
    for(int i = 1; i <= q; i++)
    {
        scanf("%d %d", &l, &r);
        R[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++)//右边界为i
    {
        int x = a[i], p = i;
        for(int j = max_base; j >= 0 ;j--)
        {
            if(x>>j&1)
            {
                if(!val[j])//填入
                {
                    val[j] = x;
                    pos[j] = p;
                    break;
                }
                if(pos[j] < p) swap(val[j], x), swap(pos[j], p);
                x ^= val[j];
            }
        }
        for(int j = 0; j < R[i].size(); j++)
        {
            for(int k = max_base; k >= 0; k--)
                if(R[i][j].first <= pos[k] && val[k])
                    ans[R[i][j].second] = max(ans[R[i][j].second], ans[R[i][j].second]^val[k]);
        }
    }
    for(int i = 1; i <= q; i++)
        cout << ans[i] << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
const int max_base = 20;
int n, q, l, r;
int a[maxn], val[max_base+3], pos[max_base+3], ans[maxn];
vector<pair<int, int> > R[1000005];//R[i]存右边界为i的区间，key表示左边界，value表示对应的编号
int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    scanf("%d",&n);
    for(int i = 1; i <= n; i++)
        scanf("%d",&a[i]);
    scanf("%d",&q);
    for(int i = 1; i <= q; i++)
    {
        scanf("%d %d", &l, &r);
        R[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++)//右边界为i
    {
        int x = a[i], p = i;
        for(int j = max_base; j >= 0 ;j--)
        {
            if(x>>j&1)
            {
                if(!val[j])//填入
                {
                    val[j] = x;
                    pos[j] = p;
                    break;
                }
                if(pos[j] < p) swap(val[j], x), swap(pos[j], p);
                x ^= val[j];
            }
        }
        for(int j = 0; j < R[i].size(); j++)
        {
            for(int k = max_base; k >= 0; k--)
                if(R[i][j].first <= pos[k] && val[k])
                    ans[R[i][j].second] = max(ans[R[i][j].second], ans[R[i][j].second]^val[k]);
        }
    }
    for(int i = 1; i <= q; i++)
        cout << ans[i] << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
const int max_base = 20;
int n, q, l, r;
int a[maxn], val[max_base+3], pos[max_base+3], ans[maxn];
vector<pair<int, int> > R[1000005];//R[i]存右边界为i的区间，key表示左边界，value表示对应的编号
int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    cin >> q;
    for(int i = 1; i <= q; i++)
    {
        cin >> l >> r;
        R[r].push_back(make_pair(l, i));
    }
    for(int i = 1; i <= n; i++)//右边界为i
    {
        int x = a[i], p = i;
        for(int j = max_base; j >= 0 ;j--)
        {
            if(x>>j&1)
            {
                if(!val[j])//填入
                {
                    val[j] = x;
                    pos[j] = p;
                    break;
                }
                if(pos[j] < p) swap(val[j], x), swap(pos[j], p);
                x ^= val[j];
            }
        }
        for(int j = 0; j < R[i].size(); j++)
        {
            for(int k = max_base; k >= 0; k--)
                if(R[i][j].first <= pos[k] && val[k])
                    ans[R[i][j].second] = max(ans[R[i][j].second], ans[R[i][j].second]^val[k]);
        }
    }
    for(int i = 1; i <= q; i++)
        cout << ans[i] << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
const int max_base = 20;
int n, q, l, r;
int a[maxn], val[max_base+3], pos[max_base+3], ans[maxn];
vector<pair<int, int> > R[1000005];//R[i]存右边界为i的区间，key表示左边界，value表示对应的编号
void solve()
{
    for(int i = 1; i <= n; i++)//右边界为i
    {
        int x = a[i], p = i;
        for(int j = max_base; j >= 0 ;j--)
        {
            if(x>>j&1)
            {
                if(!val[j])//填入
                {
                    val[j] = x;
                    pos[j] = p;
                    break;
                }
                if(pos[j] < p) swap(val[j], x), swap(pos[j], p);
                x ^= val[j];
            }
        }
        for(int j = 0; j < R[i].size(); j++)
        {
            for(int k = max_base; k >= 0; k--)
                if(R[i][j].first <= pos[k] && val[k])
                    ans[R[i][j].second] = max(ans[R[i][j].second], ans[R[i][j].second]^val[k]);
        }
    }
}
int main()
{
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    cin >> q;
    for(int i = 1; i <= q; i++)
    {
        cin >> l >> r;
        R[r].push_back(make_pair(l, i));
    }
    solve();
    for(int i = 1; i <= q; i++)
        cout << ans[i] << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn=500005;
const int max_base=20;
typedef long long ll;
int a[maxn],xian[4*maxn][max_base+3],ans[max_base+3];
int n,q,t,L,R,m,op;
void update(int id)
{
    int x=id<<1,y=id<<1|1;
    memcpy(xian[id],xian[x],sizeof(xian[x]));//id的线性基初始化左子树的线性基
    for(int k=max_base;k>=0;k--)
    {
        int tmp=xian[y][k];
        for(int j=max_base;j>=0 && tmp;j--)
        {
            if(tmp>>j&1)
            {
                if(xian[id][j])
                    tmp^=xian[id][j];
                else
                {
                    xian[id][j]=tmp;
                    break;
                }
            }
        }
    }
}
void build(int l,int r,int id)
{
    if(l==r)
    {
        for(int i=max_base;i>=0;i--)
            if(a[l]>>i&1)
            {
                if(xian[id][i])
                    a[l]^=xian[id][i];
                else
                {
                    xian[id][i]=a[l];
                    break;
                }
            }
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,id<<1);
    build(mid+1,r,id<<1|1);
    update(id);
}
void query(int l,int r,int x,int y,int id)//要查的区间为（x,y）
{
    if(x<=l && r<=y)//如果区间不能直接查到的话，线性基合并,合并的结果存入ans【】中
    {
        for(int k=max_base;k>=0;k--)
        {
            int tmp=xian[id][k];
            for(int j=max_base;j>=0 && tmp;j--)
            {
                if(tmp>>j&1)
                {
                    if(ans[j])
                        tmp^=ans[j];
                    else
                    {
                        ans[j]=tmp;
                        break;
                    }
                }
            }
        }
        return ;//记得写！
    }
    int mid=(l+r)>>1;
    if(x<=mid) query(l,mid,x,y,id<<1);
    if(y>=mid+1) query(mid+1,r,x,y,id<<1|1);
}
int main() {
    //freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
        memset(xian,0,sizeof(xian));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        build(1,n,1);
        scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            memset(ans,0,sizeof(ans));
            scanf("%d %d",&L,&R);
            int res=0;
            query(1,n,L,R,1);
            for(int j=max_base;j>=0;j--)
                res=max(res,res^ans[j]);
            printf("%d\n",res);
        }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int n,m,_;
int x,ans;

struct node
{
    int m;
    int xian[31];
    int insert(int x){
        for(int j=30;j>=0;j--) {
            if(!(x>>j&1)) continue;
            if(!xian[j]) { xian[j]=x; m++;return 1; }
            x^=xian[j];
        }
        return 0;
    }
    void clear(){
        for(int i=0;i<=30;++i) xian[i]=0;
        m=0;
    }
}sum[N*4];

void up(int id,int l,int r,int pos,int x)
{
    sum[id].insert(x);
    if(l==r)
    {
        return ;
    }
    int mid=l+r>>1;
    int ls=id<<1;
    int rs=id<<1|1;
    if(pos<=mid) up(ls,l,mid,pos,x);
    else up(rs,mid+1,r,pos,x);
}
node qu(int id,int l,int r,int ql,int qr)
{
    if(ql<=l&&r<=qr) {
        return sum[id];
    }
    int mid=l+r>>1;
    int ls=id<<1;
    int rs=id<<1|1;
    int f1=0,f2=0;
    node t1,t2,res;
    if(ql<=mid){
        t1=qu(ls,l,mid,ql,qr);

        f1=1;
    }
    if(qr>mid){
        t2=qu(rs,mid+1,r,ql,qr);
        f2=1;
    }
    if(f1&&f2)
    {
        res=t1;
        for(int i=30;i>=0;--i)
            if(t2.xian[i]) res.insert(t2.xian[i]);
    }
    else if(f1) res=t1;
    else if(f2) res=t2;
    return res;
}

void init()
{
    for(int i=1;i<=3*n;++i) sum[i]=sum[0];
}
int main()
{
    sum[0].clear();

        scanf("%d",&n);
        int lastans=0;
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&x);
            up(1,1,n,i,x);
        }
        scanf("%d",&m);
        while(m--)
        {

            int l,r;
            scanf("%d%d",&l,&r);
            node tmp=qu(1,1,n,l,r);
            ans=0;
            for(int i=30;i>=0;i--)
            {
                if((ans^tmp.xian[i])>ans) {
                    ans=ans^tmp.xian[i];
                }
            }
            printf("%d\n",ans);

        }

    return 0;
}
/*
4
7 2 3 4
100
1 3
*/


#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,_;
int x,ans;

struct node
{
    int m;
    int xian[31];
    int insert(int x){
        for(int j=30;j>=0;j--) {
            if(!(x>>j&1)) continue;
            if(!xian[j]) { xian[j]=x; m++;return 1; }
            x^=xian[j];
        }
        return 0;
    }
    void clear(){
        for(int i=0;i<=30;++i) xian[i]=0;
        m=0;
    }
}sum[N*3];

void up(int id,int l,int r,int pos,int x)
{
    sum[id].insert(x);
    if(l==r)
    {
        return ;
    }
    int mid=l+r>>1;
    int ls=id<<1;
    int rs=id<<1|1;
    if(pos<=mid) up(ls,l,mid,pos,x);
    else up(rs,mid+1,r,pos,x);
}
node qu(int id,int l,int r,int ql,int qr)
{
    if(ql<=l&&r<=qr) {
        return sum[id];
    }
    int mid=l+r>>1;
    int ls=id<<1;
    int rs=id<<1|1;
    int f1=0,f2=0;
    node t1,t2,res;
    if(ql<=mid){
        t1=qu(ls,l,mid,ql,qr);

        f1=1;
    }
    if(qr>mid){
        t2=qu(rs,mid+1,r,ql,qr);
        f2=1;
    }
    if(f1&&f2)
    {
        res=t1;
        for(int i=30;i>=0;--i)
            if(t2.xian[i]) res.insert(t2.xian[i]);
    }
    else if(f1) res=t1;
    else if(f2) res=t2;
    return res;
}

void init()
{
    for(int i=1;i<=3*n;++i) sum[i]=sum[0];
}
int main()
{
    sum[0].clear();

        scanf("%d",&n);
        int lastans=0;
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&x);
            up(1,1,n,i,x);
        }
        scanf("%d",&m);
        while(m--)
        {

            int l,r;
            scanf("%d%d",&l,&r);
            node tmp=qu(1,1,n,l,r);
            ans=0;
            for(int i=30;i>=0;i--)
            {
                if((ans^tmp.xian[i])>ans) {
                    ans=ans^tmp.xian[i];
                }
            }
            printf("%d\n",ans);

        }

    return 0;
}
/*
4
7 2 3 4
100
1 3
*/


#include <bits/stdc++.h>
using namespace std;

const int N=1e6+10;

int n,m,_;
int x;

struct node
{
    int m;
    int xian[31];
    int pos[31];
    void insert(int x,int id){
        for(int j=30;j>=0;j--) {
            if((x>>j&1)==0) continue;
            if(!xian[j])
            {
                xian[j]=x;
                pos[j]=id;
                m++;
            }
            if(pos[j]<id)
            {
                swap(x,xian[j]);
                swap(id,pos[j]);
            }
            x^=xian[j];
        }
    }
    void clear(){
        for(int i=0;i<=30;++i) xian[i]=0;
        m=0;
    }
}sum[N];

void init()
{
    for(int i=1;i<=n;++i) sum[i].clear();
}
int main()
{

        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&x);
            sum[i]=sum[i-1];
            sum[i].insert(x,i);
        }
        int lastans=0;
        scanf("%d",&m);
        while(m--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            //printf("l:%d r:%d\n",l,r);
            lastans=0;
            for(int i=30;i>=0;i--)
            {
                if(sum[r].pos[i]>=l&&(lastans^sum[r].xian[i])>lastans)
                    lastans^=sum[r].xian[i];
            }
            printf("%d\n",lastans);
        }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N=1e6+10;

int n,m,_;
int x;

struct node
{
    int m;
    int xian[31];
    int pos[31];
    void insert(int x,int id){
        for(int j=30;j>=0;j--) {
            if((x>>j&1)==0) continue;
            if(!xian[j])
            {
                xian[j]=x;
                pos[j]=id;
                m++;
            }
            if(pos[j]<id)
            {
                swap(x,xian[j]);
                swap(id,pos[j]);
            }
            x^=xian[j];
        }
    }
    void clear(){
        for(int i=0;i<=30;++i) xian[i]=0;
        m=0;
    }
}sum[N];

void init()
{
    for(int i=1;i<=n;++i) sum[i].clear();
}
int main()
{
    scanf("%d",&_);
    while(_--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&x);
            sum[i]=sum[i-1];
            sum[i].insert(x,i);
        }
        int lastans=0;
        while(m--)
        {

            int l,r;
            scanf("%d%d",&l,&r);
            lastans=0;
            for(int i=30;i>=0;i--)
            {
                if(sum[r].pos[i]>=l&&(lastans^sum[r].xian[i])>lastans)
                    lastans^=sum[r].xian[i];
            }
            printf("%d\n",lastans);
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct dat{
	int a[20],l,r;
	dat(){memset(a,0,sizeof a);}
	int solve(){
		int res = 0;
		rrep(i,19,0) res = max(res, a[i]^res);
		return res;
	}
	void print(){
		rep(i,0,19)printf("%d-%d ",i,a[i]);printf("\n");
	}
}tr[(1<<20)+5];
int n,q,l,r,a[N];

dat merge(dat x, dat y){
	dat z = x;
	rep(i,0,19)if(y.a[i]){
		rrep(j,i,0){
			if(!z.a[j] && (y.a[i]>>j&1)){
				z.a[j] = y.a[i];
				break;
			}
			if(y.a[i]>>j&1) y.a[i] ^= z.a[j];
		}
	}
	return z;
}

void build(int l=1,int r=n,int i=1){
	if(l==r){
		if(a[l]) tr[i].a[(int)log2(a[l])] = a[l];
		tr[i].l = tr[i].r = l;
		return;
	}
	int mid = l+r>>1;
	if(mid>=l) build(l,mid,i<<1);
	if(mid<r) build(mid+1,r,i<<1|1);
	tr[i] = merge(tr[i<<1], tr[i<<1|1]);
	tr[i].l = l, tr[i].r = r;
}

dat query(int l,int r,int i=1){
	int l1 = tr[i].l, r1 = tr[i].r;
	if(l<=l1 && r1<=r) return tr[i];
	int mid = l1 + r1 >> 1;
	dat x, y;
	if(mid>=l) x = query(l, r, i<<1);
	if(mid<r) y = query(l, r, i<<1|1);
	return merge(x, y);
}

int main(){
	//freopen("test.in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	build();
	scanf("%d",&q);
	rep(i,1,q){
		scanf("%d%d",&l,&r);
		dat x = query(l,r);
		printf("%d\n",x.solve());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct dat{
	int a[20],l,r,cnt=0,ma=0;
	dat(){memset(a,0,sizeof a);}
	int solve(){
		int res = 0;
		rrep(i,19,0) res = max(res, a[i]^res);
		return res;
	}
	void print(){
		printf("l=%d r=%d cnt=%d ma=%d ",l,r,cnt,ma);
		rep(i,0,19)printf("%d-%d ",i,a[i]);printf("\n");
	}
}tr[(1<<20)+5];
int n,q,l,r,a[N];

dat merge(dat x, dat y){
	if(x.cnt>x.ma || y.cnt==0) return x;
	if(x.cnt==0 || y.cnt>y.ma) return y;
	dat z = x;
	rep(i,0,19)if(y.a[i]){
		rrep(j,19,0){
			if(!z.a[j] && (y.a[i]>>j&1)){
				z.a[j] = y.a[i];
				++z.cnt, z.ma = max(z.ma, j);
				break;
			}
			if(y.a[i]>>j&1) y.a[i] ^= z.a[j];
		}
	}
	return z;
}

void build(int l=1,int r=n,int i=1){
	if(l==r){
		if(a[l]==0) return;
		int x = log2(a[l]);
		tr[i].a[x] = a[l];
		tr[i].l = tr[i].r = l;
		tr[i].cnt = 1, tr[i].ma = x;
		return;
	}
	int mid = l+r>>1;
	if(mid>=l) build(l,mid,i<<1);
	if(mid<r) build(mid+1,r,i<<1|1);
	tr[i] = merge(tr[i<<1], tr[i<<1|1]);
	tr[i].l = l, tr[i].r = r;
}

dat query(int l,int r,int i=1){
	int l1 = tr[i].l, r1 = tr[i].r;
	if(l<=l1 && r1<=r) return tr[i];
	int mid = l1 + r1 >> 1;
	dat x, y;
	if(mid>=l) x = query(l, r, i<<1);
	if(mid<r) y = query(l, r, i<<1|1);
	return merge(x, y);
}

int main(){
	//freopen("test.in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	build();
	scanf("%d",&q);
	rep(i,1,q){
		scanf("%d%d",&l,&r);
		dat x = query(l,r);
		printf("%d\n",x.solve());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(i=(a);i<=(b);++i)
#define rrep(i,a,b) for(i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n,q,r,a[N],l[N],ans[N],b[30],bi[30];
vector<int> w[N];

int main(){
	//freopen("test.in","r",stdin);
	register int i, j;
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	scanf("%d",&q);
	rep(i,1,q)scanf("%d%d",&l[i],&r),w[r].PB(i);
	memset(b,0,sizeof b);
	memset(bi,0,sizeof bi);
	memset(ans,0,sizeof ans);
	rep(i,1,n){
		int x = a[i], p = i;
		rrep(j,19,0)if(x>>j&1){
			if(!b[j]){
				b[j] = x, bi[j] = p;
				break;
			}
			if(bi[j]<p) swap(bi[j],p), swap(b[j],x);
			x ^= b[j];
		}
		for(auto x:w[i]) rrep(j,19,0){
			if(bi[j]>=l[x]) ans[x] = max(ans[x], b[j]^ans[x]);
		}
	}
	rep(i,1,q)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N = 5e5+5;

int a[N],l[N],ans[N],b[30],bi[30];
vector<int> w[N];

int main(){
	register int n,q,r,i,j,x,p;
	scanf("%d",&n);
	for(i=1;i<=n;++i)scanf("%d",a+i);
	scanf("%d",&q);
	for(i=1;i<=q;++i)scanf("%d%d",&l[i],&r),w[r].push_back(i);
	for(i=1;i<=n;++i){
		x = a[i], p = i;
		for(j=19;~j;--j)if(x>>j&1){
			if(!b[j]){
				b[j] = x, bi[j] = p;
				break;
			}
			if(bi[j]<p) swap(bi[j],p), swap(b[j],x);
			x ^= b[j];
		}
		for(auto x:w[i]) for(j=19;~j;--j){
			if(bi[j]>=l[x]) ans[x] = max(ans[x], b[j]^ans[x]);
		}
	}
	for(i=1;i<=q;++i)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(i=(a);i<=(b);++i)
#define rrep(i,a,b) for(i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int a[N],l[N],ans[N],b[30],bi[30];
vector<int> w[N];

int main(){
	//freopen("test.in","r",stdin);
	register int n,q,r,i,j;
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	scanf("%d",&q);
	rep(i,1,q)scanf("%d%d",&l[i],&r),w[r].PB(i);
	memset(b,0,sizeof b);
	memset(bi,0,sizeof bi);
	memset(ans,0,sizeof ans);
	rep(i,1,n){
		int x = a[i], p = i;
		rrep(j,19,0)if(x>>j&1){
			if(!b[j]){
				b[j] = x, bi[j] = p;
				break;
			}
			if(bi[j]<p) swap(bi[j],p), swap(b[j],x);
			x ^= b[j];
		}
		for(auto x:w[i]) rrep(j,19,0){
			if(bi[j]>=l[x]) ans[x] = max(ans[x], b[j]^ans[x]);
		}
	}
	rep(i,1,q)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N = 5e5+5;

int a[N],l[N],ans[N],b[30],bi[30];
vector<int> w[N];

int main(){
	int n,q,r,i,j,x,p;
	scanf("%d",&n);
	for(i=1;i<=n;++i)scanf("%d",a+i);
	scanf("%d",&q);
	for(i=1;i<=q;++i)scanf("%d%d",&l[i],&r),w[r].push_back(i);
	for(i=1;i<=n;++i){
		x = a[i], p = i;
		for(j=19;~j;--j)if(x>>j&1){
			if(!b[j]) {b[j] = x; bi[j] = p; break; }
			if(bi[j]<p) swap(bi[j],p), swap(b[j],x);
			x ^= b[j];
		}
		for(auto x:w[i]) for(j=19;~j;--j){
			if(bi[j]>=l[x]) ans[x] = max(ans[x], b[j]^ans[x]);
		}
	}
	for(i=1;i<=q;++i)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n,q,r,a[N],l[N],ans[N],b[30],bi[30];
vector<int> w[N];

int main(){
	//freopen("test.in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	scanf("%d",&q);
	rep(i,1,q)scanf("%d%d",&l[i],&r),w[r].PB(i);
	memset(b,0,sizeof b);
	memset(bi,0,sizeof bi);
	memset(ans,0,sizeof ans);
	rep(i,1,n){
		int x = a[i], p = i;
		if(x){
			for(int j=19;~j;--j)if(x>>j&1){
				if(!b[j]){
					b[j] = x, bi[j] = p;
					break;
				}
				if(bi[j]<p) swap(bi[j],p), swap(b[j],x);
				x ^= b[j];
			}
		}
		for(auto x:w[i]) for(int j=19;~j;--j){
			if(bi[j]>=l[x]) ans[x] = max(ans[x], b[j]^ans[x]);
		}
	}
	rep(i,1,q)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n,q,r,a[N],l[N],ans[N],b[30],bi[30];
vector<int> w[N];

int main(){
	//freopen("test.in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	scanf("%d",&q);
	rep(i,1,q)scanf("%d%d",&l[i],&r),w[r].PB(i);
	memset(b,0,sizeof b);
	memset(bi,0,sizeof bi);
	memset(ans,0,sizeof ans);
	rep(i,1,n){
		int x = a[i], p = i;
		rrep(j,19,0)if(x>>j&1){
			if(!b[j]){
				b[j] = x, bi[j] = p;
				break;
			}
			if(bi[j]<p) swap(bi[j],p), swap(b[j],x);
			x ^= b[j];
		}
		for(auto x:w[i]) rrep(j,19,0){
			if(bi[j]>=l[x]) ans[x] = max(ans[x], b[j]^ans[x]);
		}
	}
	rep(i,1,q)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct dat{
	int a[20],l,r,cnt=0,ma=0;
	dat(){memset(a,0,sizeof a);}
	int solve(){
		int res = 0;
		rrep(i,19,0) res = max(res, a[i]^res);
		return res;
	}
	void print(){
		printf("l=%d r=%d cnt=%d ma=%d ",l,r,cnt,ma);
		rep(i,0,19)printf("%d-%d ",i,a[i]);printf("\n");
	}
}tr[(1<<20)+5];
int n,q,l,r,a[N];

dat merge(dat x, dat y){
	if(x.cnt>x.ma || y.cnt==0) return x;
	if(x.cnt==0 || y.cnt>y.ma) return y;
	dat z = x;
	rep(i,0,19)if(y.a[i]){
		rrep(j,19,0){
			if(!z.a[j] && (y.a[i]>>j&1)){
				z.a[j] = y.a[i];
				++z.cnt, z.ma = max(z.ma, j);
				break;
			}
			if(y.a[i]>>j&1) y.a[i] ^= z.a[j];
		}
	}
	return z;
}

void build(int l=1,int r=n,int i=1){
	if(l==r){
		tr[i].l = tr[i].r = l;
		if(a[l]==0) return;
		int x = log2(a[l]);
		tr[i].a[x] = a[l];
		tr[i].cnt = 1, tr[i].ma = x;
		return;
	}
	int mid = l+r>>1;
	if(mid>=l) build(l,mid,i<<1);
	if(mid<r) build(mid+1,r,i<<1|1);
	tr[i] = merge(tr[i<<1], tr[i<<1|1]);
	tr[i].l = l, tr[i].r = r;
}

dat query(int l,int r,int i=1){
	int l1 = tr[i].l, r1 = tr[i].r;
	if(l<=l1 && r1<=r) return tr[i];
	int mid = l1 + r1 >> 1;
	dat x, y;
	if(mid>=l) x = query(l, r, i<<1);
	if(mid<r) y = query(l, r, i<<1|1);
	return merge(x, y);
}

int main(){
	//freopen("test.in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	build();
	scanf("%d",&q);
	rep(i,1,q){
		scanf("%d%d",&l,&r);
		dat x = query(l,r);
		printf("%d\n",x.solve());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct dat{
	int a[20],l,r;
	dat(){memset(a,0,sizeof a);}
	int solve(){
		int res = 0;
		rrep(i,19,0) res = max(res, a[i]^res);
		return res;
	}
	void print(){
		rep(i,0,19)printf("%d-%d ",i,a[i]);printf("\n");
	}
}tr[(1<<20)+5];
int n,q,l,r,a[N];

dat merge(dat x, dat y){
	dat z = x;
	rep(i,0,19)if(y.a[i]){
		rrep(j,i,0){
			if(!z.a[j] && (y.a[i]>>j&1)){
				z.a[j] = y.a[i];
				break;
			}
			if(y.a[i]>>j&1) y.a[i] ^= z.a[j];
		}
	}
	return z;
}

void build(int l=1,int r=n,int i=1){
	if(l==r){
		int x = log2(a[l]);
		if(x) tr[i].a[x] = a[l];
		tr[i].l = tr[i].r = l;
		return;
	}
	int mid = l+r>>1;
	if(mid>=l) build(l,mid,i<<1);
	if(mid<r) build(mid+1,r,i<<1|1);
	tr[i] = merge(tr[i<<1], tr[i<<1|1]);
	tr[i].l = l, tr[i].r = r;
}

dat query(int l,int r,int i=1){
	int l1 = tr[i].l, r1 = tr[i].r;
	if(l<=l1 && r1<=r) return tr[i];
	int mid = l1 + r1 >> 1;
	dat x, y;
	if(mid>=l) x = query(l, r, i<<1);
	if(mid<r) y = query(l, r, i<<1|1);
	return merge(x, y);
}

int main(){
	//freopen("test.in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	build();
	scanf("%d",&q);
	rep(i,1,q){
		scanf("%d%d",&l,&r);
		dat x = query(l,r);
		printf("%d\n",x.solve());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct dat{
	int a[20],l,r;
	dat(){memset(a,0,sizeof a);}
	int solve(){
		int res = 0;
		rrep(i,19,0) res = max(res, a[i]^res);
		return res;
	}
	void print(){
		rep(i,0,19)printf("%d-%d ",i,a[i]);printf("\n");
	}
}tr[(1<<20)+5];
int n,q,l,r,a[N];

dat merge(dat x, dat y){
	dat z = x;
	rep(i,0,19)if(y.a[i]){
		rrep(j,i,0){
			if(!z.a[j] && (y.a[i]>>j&1)){
				z.a[j] = y.a[i];
				break;
			}
			if(y.a[i]>>j&1) y.a[i] ^= z.a[j];
		}
	}
	return z;
}

void build(int l=1,int r=n,int i=1){
	if(l==r){
		if(a[l]) tr[i].a[log2(a[l])] = a[l];
		tr[i].l = tr[i].r = l;
		return;
	}
	int mid = l+r>>1;
	if(mid>=l) build(l,mid,i<<1);
	if(mid<r) build(mid+1,r,i<<1|1);
	tr[i] = merge(tr[i<<1], tr[i<<1|1]);
	tr[i].l = l, tr[i].r = r;
}

dat query(int l,int r,int i=1){
	int l1 = tr[i].l, r1 = tr[i].r;
	if(l<=l1 && r1<=r) return tr[i];
	int mid = l1 + r1 >> 1;
	dat x, y;
	if(mid>=l) x = query(l, r, i<<1);
	if(mid<r) y = query(l, r, i<<1|1);
	return merge(x, y);
}

int main(){
	//freopen("test.in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	build();
	scanf("%d",&q);
	rep(i,1,q){
		scanf("%d%d",&l,&r);
		dat x = query(l,r);
		printf("%d\n",x.solve());
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(i=(a);i<=(b);++i)
#define rrep(i,a,b) for(i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int a[N],l[N],ans[N],b[30],bi[30];
vector<int> w[N];

int main(){
	//freopen("test.in","r",stdin);
	register int n,q,r,i,j,x,p;
	scanf("%d",&n);
	for(i=1;i<=n;++i)scanf("%d",a+i);
	scanf("%d",&q);
	for(i=1;i<=q;++i)scanf("%d%d",&l[i],&r),w[r].PB(i);
	memset(b,0,sizeof b);
	memset(bi,0,sizeof bi);
	memset(ans,0,sizeof ans);
	for(i=1;i<=n;++i){
		x = a[i], p = i;
		for(j=19;~j;--j)if(x>>j&1){
			if(!b[j]){
				b[j] = x, bi[j] = p;
				break;
			}
			if(bi[j]<p) swap(bi[j],p), swap(b[j],x);
			x ^= b[j];
		}
		for(auto x:w[i]) for(j=19;~j;--j){
			if(bi[j]>=l[x]) ans[x] = max(ans[x], b[j]^ans[x]);
		}
	}
	for(i=1;i<=q;++i)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
#define MP make_pair
#define PB push_back
#define PII pair<int,int>
typedef long long LL;
const LL P = 1e9+7;
const int N = 5e5+5;
const LL INF = 1e16;
const double pi = acos(-1);
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

struct dat{
	int a[20],l,r;
	dat(){memset(a,0,sizeof a);}
	int solve(){
		int res = 0;
		rrep(i,19,0) res = max(res, a[i]^res);
		return res;
	}
	void print(){
		rep(i,0,19)printf("%d-%d ",i,a[i]);printf("\n");
	}
}tr[(1<<20)+5];
int n,q,l,r,a[N];

dat merge(dat x, dat y){
	dat z = x;
	rep(i,0,19)if(y.a[i]){
		rrep(j,19,0){
			if(!z.a[j] && (y.a[i]>>j&1)){
				z.a[j] = y.a[i];
				break;
			}
			if(y.a[i]>>j&1) y.a[i] ^= z.a[j];
		}
	}
	return z;
}

void build(int l=1,int r=n,int i=1){
	if(l==r){
		int x = log2(a[l]);
		tr[i].a[x] = a[l];
		tr[i].l = tr[i].r = l;
		return;
	}
	int mid = l+r>>1;
	if(mid>=l) build(l,mid,i<<1);
	if(mid<r) build(mid+1,r,i<<1|1);
	tr[i] = merge(tr[i<<1], tr[i<<1|1]);
	tr[i].l = l, tr[i].r = r;
}

dat query(int l,int r,int i=1){
	int l1 = tr[i].l, r1 = tr[i].r;
	if(l<=l1 && r1<=r) return tr[i];
	int mid = l1 + r1 >> 1;
	dat x, y;
	if(mid>=l) x = query(l, r, i<<1);
	if(mid<r) y = query(l, r, i<<1|1);
	return merge(x, y);
}

int main(){
	//freopen("test.in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n)scanf("%d",a+i);
	build();
	scanf("%d",&q);
	rep(i,1,q){
		scanf("%d%d",&l,&r);
		dat x = query(l,r);
		printf("%d\n",x.solve());
	}
	return 0;
}


#include <string.h>
#include <unordered_map>

#include <sstream>
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <iostream>
#include   <stdlib.h>
#include   <time.h>
#include <stack>
#include <queue>
#include <set>

#include <map>
#include <vector>
#include <string>
#include <stdlib.h>

#define ll long long
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
#define fr(i,a,b) for(int i = a; i < b; ++i)
#define frr(i,a,b) for(int i = a; i > b; --i)
#define pb push_back
#define sf scanf

#define pf printf
#define mp make_pair

using namespace std;
const int N = 110;
int mod = 998244353;

int p[100],pos[100];
int n,q;

void add(int t, int id) {
	for(int i = 20; i >=0; --i) {
		if((1<<i)&t) {
			if(!p[i]){
				p[i] = t;
				pos[i] = id;
			}
			else {
				swap(p[i],t);
				swap(pos[i],id);

				t ^=p[i];
			}
		}
	}
}

int query(int id) {

	int res = 0;
	for(int i = 20; i >=0;--i) {
		if(p[i]&&pos[i]>=id) {
			if((res ^ p[i]) > res) res ^=p[i];
		}
	}
	return res;
}

int a[1000010];
struct Info{
	int l,r;
	int id;
};

Info ft[1000010];
int ans[1000010];

void sol(){
	auto cmp = [&](const Info &a, const Info &b) {
		return a.r < b.r;
	};

	sort(ft,ft+q,cmp);
	int idx = 1;
	for(int i = 0; i < q; ++i) {
		while(idx <= ft[i].r)  {
			add(a[idx],idx);
			idx++;
		}

		ans[ft[i].id] = query(ft[i].l);
	}
}

int main() {
	sf("%d",&n);
	fr(i,1,n+1) {
		sf("%d",&a[i]);
	}
	sf("%d",&q);
	fr(i,0,q) {
		sf("%d%d",&ft[i].l, &ft[i].r);
		ft[i].id = i;
	}
	sol();
	fr(i,0,q) {
		pf("%d\n",ans[i]);
	}
}


#include <string.h>
#include <unordered_map>

#include <sstream>
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <iostream>
#include   <stdlib.h>
#include   <time.h>
#include <stack>
#include <queue>
#include <set>

#include <map>
#include <vector>
#include <string>
#include <stdlib.h>

#define ll long long
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
#define fr(i,a,b) for(int i = a; i < b; ++i)
#define frr(i,a,b) for(int i = a; i > b; --i)
#define pb push_back
#define sf scanf

#define pf printf
#define mp make_pair

using namespace std;
const int N = 110;
int mod = 998244353;

int p[100],pos[100];
int n,q;

void add(int t, int id) {
	for(int i = 20; i >=0; --i) {
		if((1<<i)&t) {
			if(!p[i]){
				p[i] = t;
				pos[i] = id;
				return;
			}
			else {
				if(pos[i]<id) {
					swap(p[i],t);
					swap(pos[i],id);
				}
				t ^=p[i];
			}
		}
	}
}

int query(int id) {

	int res = 0;
	for(int i = 20; i >=0;--i) {
		if(p[i]&&pos[i]>=id) {
			if((res ^ p[i]) > res) res ^=p[i];
		}
	}
	return res;
}

int a[1000010];
struct Info{
	int l,r;
	int id;
};

Info ft[1000010];
int ans[1000010];

void sol(){
	clr(pos);
	clr(p);
	auto cmp = [&](const Info &a, const Info &b) {
		return a.r < b.r;
	};

	sort(ft,ft+q,cmp);
	int idx = 1;
	for(int i = 0; i < q; ++i) {
		while(idx <= ft[i].r)  {
			add(a[idx],idx);
			idx++;
		}

		ans[ft[i].id] = query(ft[i].l);
	}
}

int main() {
	sf("%d",&n);
	fr(i,1,n+1) {
		sf("%d",&a[i]);
	}
	sf("%d",&q);
	fr(i,0,q) {
		sf("%d%d",&ft[i].l, &ft[i].r);
		ft[i].id = i;
	}
	sol();
	fr(i,0,q) {
		pf("%d\n",ans[i]);
	}
}


#include <string.h>
#include <unordered_map>

#include <sstream>
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <iostream>
#include   <stdlib.h>
#include   <time.h>
#include <stack>
#include <queue>
#include <set>

#include <map>
#include <vector>
#include <string>
#include <stdlib.h>

#define ll long long
#define clr(x) memset(x,0,sizeof(x))
#define _clr(x) memset(x,-1,sizeof(x))
#define fr(i,a,b) for(int i = a; i < b; ++i)
#define frr(i,a,b) for(int i = a; i > b; --i)
#define pb push_back
#define sf scanf

#define pf printf
#define mp make_pair

using namespace std;
const int N = 110;
int mod = 998244353;

int p[100],pos[100];
int n,q;

void add(int t, int id) {
	for(int i = 20; i >=0; --i) {
		if((1<<i)&t) {
			if(!p[i]){
				p[i] = t;
				pos[i] = id;
				return;
			}
			else {
				swap(p[i],t);
				swap(pos[i],id);

				t ^=p[i];
			}
		}
	}
}

int query(int id) {

	int res = 0;
	for(int i = 20; i >=0;--i) {
		if(p[i]&&pos[i]>=id) {
			if((res ^ p[i]) > res) res ^=p[i];
		}
	}
	return res;
}

int a[1000010];
struct Info{
	int l,r;
	int id;
};

Info ft[1000010];
int ans[1000010];

void sol(){
	auto cmp = [&](const Info &a, const Info &b) {
		return a.r < b.r;
	};

	sort(ft,ft+q,cmp);
	int idx = 1;
	for(int i = 0; i < q; ++i) {
		while(idx <= ft[i].r)  {
			add(a[idx],idx);
			idx++;
		}

		ans[ft[i].id] = query(ft[i].l);
	}
}

int main() {
	sf("%d",&n);
	fr(i,1,n+1) {
		sf("%d",&a[i]);
	}
	sf("%d",&q);
	fr(i,0,q) {
		sf("%d%d",&ft[i].l, &ft[i].r);
		ft[i].id = i;
	}
	sol();
	fr(i,0,q) {
		pf("%d\n",ans[i]);
	}
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cassert>

const int kMaxCBits = 21;
const int kMaxC = 1000010;
const int kMaxN = 524288;

// holds linearly independent vectors
// invariant: i-th vector has i-th leading bit, and no other vectors have this
// bit set.
struct Set {
  Set() : has_vector_mask(0) {}

  static int leading_bit(int x) {
    assert(x > 0);
    return x == 1 ? 0 : 1 + leading_bit(x / 2);
  }

  static bool has_bit(int x, int c) {
    return !!(x & (1 << c));
  }

  int has_vector(int c) const {
    return has_bit(has_vector_mask, c);
  }

  // O(kMaxCBits)
  void add(int x) {
    assert(x < kMaxC);

    // Remove all bits that we already know how to get.
    while ((has_vector_mask & x)) {
      int intersection = (has_vector_mask & x);
      x ^= vectors[leading_bit(intersection)];
    }
    if (!x) {
      return;
    }

    int lead_x = leading_bit(x);
    assert(lead_x < kMaxCBits);
    assert(!has_vector(lead_x));

    vectors[lead_x] = x;
    has_vector_mask |= (1 << lead_x);

    // Vectors above me shouldn't have this bit set.
    // Vectors below me can't have this bit set because their leading bit
    // is below.
    for (int i = lead_x + 1; i < kMaxCBits; ++i) {
      if (has_vector(i) && has_bit(vectors[i], lead_x)) {
        vectors[i] ^= x;
      }
    }
  }

  // O(kMaxCBits ^ 2)
  void test_invariants() const {
    for (int i = kMaxCBits - 1; i >= 0; --i) {
      if (!has_vector(i)) {
        continue;
      }
      printf("%2d: ", i);
      for (int j = kMaxCBits - 1; j >= 0; --j) {
        printf("%d", (has_bit(vectors[i], j)));
      }
      printf("\n");
    }
    int max = get_max();
    printf("xx: ");
    for (int j = kMaxCBits - 1; j >= 0; --j) {
      printf("%d", (has_bit(max, j)));
    }
    printf("\n");

    for (int i = 0; i < kMaxCBits; ++i) {
      if (!has_vector(i)) {
        continue;
      }
      assert(leading_bit(vectors[i]) == i);
      for (int j = 0; j < kMaxCBits; ++j) {
        if (i == j || !has_vector(j)) {
          continue;
        }
        assert(!has_bit(vectors[j], i));
      }
    }
  }

  // O(kMaxCBits)
  // returns the max Xor that we can get from this set.
  int get_max() const {
    int sol = 0;
    for (int i = kMaxCBits - 1; i >= 0; --i) {
      if (has_vector(i)) {
        assert(has_bit(vectors[i], i));
        if (!has_bit(sol, i)) {
          sol ^= vectors[i];
        }
      }
    }
    return sol;
  }

  int vectors[kMaxCBits];
  int has_vector_mask;
};

Set tournament[kMaxN * 2];

void load() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    int c;
    scanf("%d", &c);
    tournament[kMaxN + i].add(c);
  }
}

void merge(const Set& lhs, const Set& rhs, Set *result) {
  if (!lhs.has_vector_mask && !rhs.has_vector_mask) {
    return;
  }
  *result = lhs;
  for (int i = 0; i < kMaxCBits; ++i) {
    if (rhs.has_vector(i)) {
      result->add(rhs.vectors[i]);
    }
  }
}

void build() {
  for (int i = kMaxN - 1; i > 0; --i) {
    merge(tournament[i * 2], tournament[i * 2 + 1], &tournament[i]);
  }
}

struct Interval {
  int lo, hi;
  Interval(int lo, int hi) : lo(lo), hi(hi) {
    if (hi < lo) {
      hi = lo;
    }
  }

  Interval split_lo() const { return Interval(lo, (lo + hi) / 2); }
  Interval split_hi() const { return Interval((lo + hi) / 2, hi); }
  bool contains(int x) const { return x >= lo && x < hi; }

  int size() const { return hi - lo; }
  Interval intersection(const Interval& other) const {
    return Interval(std::max(lo, other.lo), std::min(hi, other.hi));
  }
  bool contains(const Interval& other) const {
    return intersection(other).size() == other.size();
  }
  bool intersects(const Interval& other) const {
    return intersection(other).size() > 0;
  }
};

Set solve(int node, const Interval& node_interval, const Interval& query) {
  Set result;
  if (!node_interval.intersects(query)) {
    return result;
  }
  if (query.contains(node_interval)) {
    return tournament[node];
  }
  merge(
      solve(node * 2    , node_interval.split_lo(), query),
      solve(node * 2 + 1, node_interval.split_hi(), query),
      &result);
  return result;
}

Set brute(const Interval& query) {
  Set result;
  for (int i = query.lo; i < query.hi; ++i) {
    Set tmp = result;
    tournament[kMaxN + i].test_invariants();
    printf("\n");
    merge(tmp, tournament[kMaxN + i], &result);
  }
  result.test_invariants();
  return result;
}

int main() {
  load();
  build();

  int q;
  scanf("%d", &q);
  for (int i = 0; i < q; ++i) {
    int lo, hi;
    scanf("%d%d", &lo, &hi);
    Interval query(lo - 1, hi);
    int sol = solve(1, Interval(0, kMaxN), query).get_max();
    printf("%d\n", sol);
  }
  return 0;
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cassert>

const int kMaxCBits = 21;
const int kMaxC = 1000010;
const int kMaxN = 524288;

// holds linearly independent vectors
// invariant: i-th vector has i-th leading bit, and no other vectors have this
// bit set.
struct Set {
  Set() : has_vector_mask(0) {}

  static int leading_bit(int x) {
    assert(x > 0);
    return x == 1 ? 0 : 1 + leading_bit(x / 2);
  }

  static bool has_bit(int x, int c) {
    return !!(x & (1 << c));
  }

  int has_vector(int c) const {
    return has_bit(has_vector_mask, c);
  }

  // O(kMaxCBits)
  void add(int x) {
    assert(x < kMaxC);

    // If I know how to get all bits of x, I can stop.
    if ((has_vector_mask | x) == has_vector_mask) {
      return;
    }

    // Remove all bits that we already know how to get.
    while ((has_vector_mask & x)) {
      int intersection = (has_vector_mask & x);
      x ^= vectors[leading_bit(intersection)];
    }
    // This is non zero because we didn't return in a block above.
    assert(x > 0);

    int lead_x = leading_bit(x);
    assert(lead_x < kMaxCBits);
    assert(!has_vector(lead_x));

    vectors[lead_x] = x;
    has_vector_mask |= (1 << lead_x);

    // Vectors above me shouldn't have this bit set.
    // Vectors below me can't have this bit set because their leading bit
    // is below.
    for (int i = lead_x + 1; i < kMaxCBits; ++i) {
      if (has_vector(i) && has_bit(vectors[i], lead_x)) {
        vectors[i] ^= x;
      }
    }
  }

  // O(kMaxCBits ^ 2)
  void test_invariants() const {
    for (int i = kMaxCBits - 1; i >= 0; --i) {
      if (!has_vector(i)) {
        continue;
      }
      printf("%2d: ", i);
      for (int j = kMaxCBits - 1; j >= 0; --j) {
        printf("%d", (has_bit(vectors[i], j)));
      }
      printf("\n");
    }
    int max = get_max();
    printf("xx: ");
    for (int j = kMaxCBits - 1; j >= 0; --j) {
      printf("%d", (has_bit(max, j)));
    }
    printf("\n");

    for (int i = 0; i < kMaxCBits; ++i) {
      if (!has_vector(i)) {
        continue;
      }
      assert(leading_bit(vectors[i]) == i);
      for (int j = 0; j < kMaxCBits; ++j) {
        if (i == j || !has_vector(j)) {
          continue;
        }
        assert(!has_bit(vectors[j], i));
      }
    }
  }

  // O(kMaxCBits)
  // returns the max Xor that we can get from this set.
  int get_max() const {
    int sol = 0;
    for (int i = kMaxCBits - 1; i >= 0; --i) {
      if (has_vector(i)) {
        assert(has_bit(vectors[i], i));
        if (!has_bit(sol, i)) {
          sol ^= vectors[i];
        }
      }
    }
    return sol;
  }

  int vectors[kMaxCBits];
  int has_vector_mask;
};

Set tournament[kMaxN * 2];

void load() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    int c;
    scanf("%d", &c);
    tournament[kMaxN + i].add(c);
  }
}

void merge(const Set& lhs, const Set& rhs, Set *result) {
  if (!lhs.has_vector_mask && !rhs.has_vector_mask) {
    return;
  }
  *result = lhs;
  for (int i = 0; i < kMaxCBits; ++i) {
    if (rhs.has_vector(i)) {
      result->add(rhs.vectors[i]);
    }
  }
}

void build() {
  for (int i = kMaxN - 1; i > 0; --i) {
    merge(tournament[i * 2], tournament[i * 2 + 1], &tournament[i]);
  }
}

struct Interval {
  int lo, hi;
  Interval(int lo, int hi) : lo(lo), hi(hi) {
    if (hi < lo) {
      hi = lo;
    }
  }

  Interval split_lo() const { return Interval(lo, (lo + hi) / 2); }
  Interval split_hi() const { return Interval((lo + hi) / 2, hi); }
  bool contains(int x) const { return x >= lo && x < hi; }

  int size() const { return hi - lo; }
  Interval intersection(const Interval& other) const {
    return Interval(std::max(lo, other.lo), std::min(hi, other.hi));
  }
  bool contains(const Interval& other) const {
    return intersection(other).size() == other.size();
  }
  bool intersects(const Interval& other) const {
    return intersection(other).size() > 0;
  }
};

Set solve(int node, const Interval& node_interval, const Interval& query) {
  Set result;
  if (!node_interval.intersects(query)) {
    return result;
  }
  if (query.contains(node_interval)) {
    return tournament[node];
  }
  merge(
      solve(node * 2    , node_interval.split_lo(), query),
      solve(node * 2 + 1, node_interval.split_hi(), query),
      &result);
  return result;
}

Set brute(const Interval& query) {
  Set result;
  for (int i = query.lo; i < query.hi; ++i) {
    Set tmp = result;
    //tournament[kMaxN + i].test_invariants();
    //printf("\n");
    merge(tmp, tournament[kMaxN + i], &result);
  }
  //result.test_invariants();
  return result;
}

int main() {
  load();
  build();

  int q;
  scanf("%d", &q);
  for (int i = 0; i < q; ++i) {
    int lo, hi;
    scanf("%d%d", &lo, &hi);
    Interval query(lo - 1, hi);
    int sol = solve(1, Interval(0, kMaxN), query).get_max();
    printf("%d\n", sol);
  }
  return 0;
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cassert>

const int kMaxCBits = 21;
const int kMaxC = 1000010;
const int kMaxN = 524288;

int leading_bit_memo[kMaxC];
void init_leading_bit_memo() {
  leading_bit_memo[1] = 0;
  for (int i = 2; i < kMaxC; ++i) {
    leading_bit_memo[i] = leading_bit_memo[i / 2] + 1;
  }
}

int bitcount(int x) {
  return x ? x % 2 + bitcount(x / 2) : 0;
}

// holds linearly independent vectors
// invariant: i-th vector has i-th leading bit, and no other vectors have this
// bit set.
struct Set {
  Set() : has_vector_mask(0) {}

  static int leading_bit(int x) {
    assert(x > 0);
    return leading_bit_memo[x];
  }

  static bool has_bit(int x, int c) {
    return !!(x & (1 << c));
  }

  int has_vector(int c) const {
    return has_bit(has_vector_mask, c);
  }

  // O(kMaxCBits)
  void add(int x) {
    assert(x < kMaxC);

    // Remove all bits that we already know how to get.
    while ((has_vector_mask & x)) {
      int intersection = (has_vector_mask & x);
      x ^= vectors[leading_bit(intersection)];
    }
    if (!x) {
      return;
    }

    int lead_x = leading_bit(x);
    assert(lead_x < kMaxCBits);
    assert(!has_vector(lead_x));

    vectors[lead_x] = x;
    has_vector_mask |= (1 << lead_x);

    // Vectors above me shouldn't have this bit set.
    // Vectors below me can't have this bit set because their leading bit
    // is below.
    for (int i = lead_x + 1; i < kMaxCBits; ++i) {
      if (has_vector(i) && has_bit(vectors[i], lead_x)) {
        vectors[i] ^= x;
      }
    }
  }

  // O(kMaxCBits ^ 2)
  void test_invariants() const {
    for (int i = kMaxCBits - 1; i >= 0; --i) {
      if (!has_vector(i)) {
        continue;
      }
      printf("%2d: ", i);
      for (int j = kMaxCBits - 1; j >= 0; --j) {
        printf("%d", (has_bit(vectors[i], j)));
      }
      printf("\n");
    }
    int max = get_max();
    printf("xx: ");
    for (int j = kMaxCBits - 1; j >= 0; --j) {
      printf("%d", (has_bit(max, j)));
    }
    printf("\n");

    for (int i = 0; i < kMaxCBits; ++i) {
      if (!has_vector(i)) {
        continue;
      }
      assert(leading_bit(vectors[i]) == i);
      for (int j = 0; j < kMaxCBits; ++j) {
        if (i == j || !has_vector(j)) {
          continue;
        }
        assert(!has_bit(vectors[j], i));
      }
    }
  }

  // O(kMaxCBits)
  // returns the max Xor that we can get from this set.
  int get_max() const {
    int sol = 0;
    for (int i = kMaxCBits - 1; i >= 0; --i) {
      if (has_vector(i)) {
        assert(has_bit(vectors[i], i));
        if (!has_bit(sol, i)) {
          sol ^= vectors[i];
        }
      }
    }
    return sol;
  }

  int vectors[kMaxCBits];
  int has_vector_mask;
};

Set tournament[kMaxN * 2];

void load() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    int c;
    scanf("%d", &c);
    tournament[kMaxN + i].add(c);
  }
}

void merge(const Set& lhs, const Set& rhs, Set *result) {
  if (!lhs.has_vector_mask && !rhs.has_vector_mask) {
    return;
  }
  const Set* _lhs = &lhs;
  const Set* _rhs = &rhs;
  if (bitcount(_lhs->has_vector_mask) > bitcount(_rhs->has_vector_mask)) {
    std::swap(_lhs, _rhs);
  }
  // lhs has less bits.
  *result = *_rhs;
  // ajmo skuzit kome je maska manja?
  for (int i = 0; i < kMaxCBits; ++i) {
    if (_lhs->has_vector(i)) {
      result->add(_lhs->vectors[i]);
    }
  }
}

void mergeTo(const Set& lhs, Set *result) {
  for (int i = 0; i < kMaxCBits; ++i) {
    if (lhs.has_vector(i)) {
      result->add(lhs.vectors[i]);
    }
  }
}

void build() {
  for (int i = kMaxN - 1; i > 0; --i) {
    merge(tournament[i * 2], tournament[i * 2 + 1], &tournament[i]);
  }
}

struct Interval {
  int lo, hi;
  Interval(int lo, int hi) : lo(lo), hi(hi) {
    if (hi < lo) {
      hi = lo;
    }
  }

  Interval split_lo() const { return Interval(lo, (lo + hi) / 2); }
  Interval split_hi() const { return Interval((lo + hi) / 2, hi); }
  bool contains(int x) const { return x >= lo && x < hi; }

  int size() const { return hi - lo; }
  Interval intersection(const Interval& other) const {
    return Interval(std::max(lo, other.lo), std::min(hi, other.hi));
  }
  bool contains(const Interval& other) const {
    return intersection(other).size() == other.size();
  }
  bool intersects(const Interval& other) const {
    return intersection(other).size() > 0;
  }
};

void solve(int node, const Interval& node_interval, const Interval& query,
           Set *result) {
  if (!node_interval.intersects(query)) {
    return;
  }
  if (query.contains(node_interval)) {
    mergeTo(tournament[node], result);
    return;
  }
  solve(node * 2    , node_interval.split_lo(), query, result);
  solve(node * 2 + 1, node_interval.split_hi(), query, result);
}

Set brute(const Interval& query) {
  Set result;
  for (int i = query.lo; i < query.hi; ++i) {
    Set tmp = result;
    tournament[kMaxN + i].test_invariants();
    printf("\n");
    merge(tmp, tournament[kMaxN + i], &result);
  }
  result.test_invariants();
  return result;
}

int main() {
  init_leading_bit_memo();
  load();
  build();

  int q;
  scanf("%d", &q);
  for (int i = 0; i < q; ++i) {
    int lo, hi;
    scanf("%d%d", &lo, &hi);
    Interval query(lo - 1, hi);
    Set result;
    solve(1, Interval(0, kMaxN), query, &result);
    printf("%d\n", result.get_max());
  }
  return 0;
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cassert>

const int kMaxCBits = 21;
const int kMaxC = 1000010;
const int kMaxN = 524288;

int leading_bit_memo[kMaxC];
void init_leading_bit_memo() {
  leading_bit_memo[1] = 0;
  for (int i = 2; i < kMaxC; ++i) {
    leading_bit_memo[i] = leading_bit_memo[i / 2] + 1;
  }
}

// holds linearly independent vectors
// invariant: i-th vector has i-th leading bit, and no other vectors have this
// bit set.
struct Set {
  Set() : has_vector_mask(0) {}

  static int leading_bit(int x) {
    assert(x > 0);
    return leading_bit_memo[x];
  }

  static bool has_bit(int x, int c) {
    return !!(x & (1 << c));
  }

  int has_vector(int c) const {
    return has_bit(has_vector_mask, c);
  }

  // O(kMaxCBits)
  void add(int x) {
    assert(x < kMaxC);

    // Remove all bits that we already know how to get.
    while ((has_vector_mask & x)) {
      int intersection = (has_vector_mask & x);
      x ^= vectors[leading_bit(intersection)];
    }
    if (!x) {
      return;
    }

    int lead_x = leading_bit(x);
    assert(lead_x < kMaxCBits);
    assert(!has_vector(lead_x));

    vectors[lead_x] = x;
    has_vector_mask |= (1 << lead_x);

    // Vectors above me shouldn't have this bit set.
    // Vectors below me can't have this bit set because their leading bit
    // is below.
    for (int i = lead_x + 1; i < kMaxCBits; ++i) {
      if (has_vector(i) && has_bit(vectors[i], lead_x)) {
        vectors[i] ^= x;
      }
    }
  }

  // O(kMaxCBits ^ 2)
  void test_invariants() const {
    for (int i = kMaxCBits - 1; i >= 0; --i) {
      if (!has_vector(i)) {
        continue;
      }
      printf("%2d: ", i);
      for (int j = kMaxCBits - 1; j >= 0; --j) {
        printf("%d", (has_bit(vectors[i], j)));
      }
      printf("\n");
    }
    int max = get_max();
    printf("xx: ");
    for (int j = kMaxCBits - 1; j >= 0; --j) {
      printf("%d", (has_bit(max, j)));
    }
    printf("\n");

    for (int i = 0; i < kMaxCBits; ++i) {
      if (!has_vector(i)) {
        continue;
      }
      assert(leading_bit(vectors[i]) == i);
      for (int j = 0; j < kMaxCBits; ++j) {
        if (i == j || !has_vector(j)) {
          continue;
        }
        assert(!has_bit(vectors[j], i));
      }
    }
  }

  // O(kMaxCBits)
  // returns the max Xor that we can get from this set.
  int get_max() const {
    int sol = 0;
    for (int i = kMaxCBits - 1; i >= 0; --i) {
      if (has_vector(i)) {
        assert(has_bit(vectors[i], i));
        if (!has_bit(sol, i)) {
          sol ^= vectors[i];
        }
      }
    }
    return sol;
  }

  int vectors[kMaxCBits];
  int has_vector_mask;
};

Set tournament[kMaxN * 2];

void load() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    int c;
    scanf("%d", &c);
    tournament[kMaxN + i].add(c);
  }
}

void merge(const Set& lhs, const Set& rhs, Set *result) {
  if (!lhs.has_vector_mask && !rhs.has_vector_mask) {
    return;
  }
  *result = lhs;
  for (int i = 0; i < kMaxCBits; ++i) {
    if (rhs.has_vector(i)) {
      result->add(rhs.vectors[i]);
    }
  }
}

void build() {
  for (int i = kMaxN - 1; i > 0; --i) {
    merge(tournament[i * 2], tournament[i * 2 + 1], &tournament[i]);
  }
}

struct Interval {
  int lo, hi;
  Interval(int lo, int hi) : lo(lo), hi(hi) {
    if (hi < lo) {
      hi = lo;
    }
  }

  Interval split_lo() const { return Interval(lo, (lo + hi) / 2); }
  Interval split_hi() const { return Interval((lo + hi) / 2, hi); }
  bool contains(int x) const { return x >= lo && x < hi; }

  int size() const { return hi - lo; }
  Interval intersection(const Interval& other) const {
    return Interval(std::max(lo, other.lo), std::min(hi, other.hi));
  }
  bool contains(const Interval& other) const {
    return intersection(other).size() == other.size();
  }
  bool intersects(const Interval& other) const {
    return intersection(other).size() > 0;
  }
};

Set solve(int node, const Interval& node_interval, const Interval& query) {
  Set result;
  if (!node_interval.intersects(query)) {
    return result;
  }
  if (query.contains(node_interval)) {
    return tournament[node];
  }
  merge(
      solve(node * 2    , node_interval.split_lo(), query),
      solve(node * 2 + 1, node_interval.split_hi(), query),
      &result);
  return result;
}

Set brute(const Interval& query) {
  Set result;
  for (int i = query.lo; i < query.hi; ++i) {
    Set tmp = result;
    tournament[kMaxN + i].test_invariants();
    printf("\n");
    merge(tmp, tournament[kMaxN + i], &result);
  }
  result.test_invariants();
  return result;
}

int main() {
  init_leading_bit_memo();
  load();
  build();

  int q;
  scanf("%d", &q);
  for (int i = 0; i < q; ++i) {
    int lo, hi;
    scanf("%d%d", &lo, &hi);
    Interval query(lo - 1, hi);
    int sol = solve(1, Interval(0, kMaxN), query).get_max();
    printf("%d\n", sol);
  }
  return 0;
}