#include <bits/stdc++.h>
//#include <bits/extc++.h>
//#include <ext/pb_ds/assoc_container.hpp> // Common file
//#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
 
using namespace std;
//using namespace __gnu_pbds;
//template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
 
#define int ll
 
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using ull = unsigned ll;
 
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define all(x) (x).begin(),(x).end()
#define x first
#define y second
#define PI 3.14159265
 
const int MOD = 1e9 + 7;
//const int MOD = 998244353;
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0}; 
const char dir[] = {'R', 'L', 'D', 'U'};
 
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
 
int add(int a, int b){ //(a + b) % 1e9 + 7
    a += b;
    if(a < 0){
        a += MOD;
    }
    if(a >= MOD){
        a -= MOD;
    }
    return a;
}
 
int sub(int a, int b){
    a -= b;
    if(a < 0) a += MOD;
    return a;
}
 
int mult(int a, int b){
    return ((ll) a * b) % MOD;
}
 
void setIO() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
//    freopen((s+".in").c_str(),"r",stdin);
//    freopen((s+".text").c_str(),"w",stdout);
}

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

template<class T> struct Seg { // comb(ID,b) = b
    const T ID = 0; T comb(T a, T b) { return a^b; } 
    int n; vector<T> seg;
    void init(int _n) { n = _n; seg.assign(2*n,ID); }
    void pull(int p) { seg[p] = comb(seg[2*p],seg[2*p+1]); }
    void upd(int p, T val) { // set val at position p
        seg[p += n] = val; for (p /= 2; p; p /= 2) pull(p); }
    T query(int l, int r) { // sum on interval [l, r]
        T ra = ID, rb = ID; 
        for (l += n, r += n+1; l < r; l /= 2, r /= 2) {
            if (l&1) ra = comb(ra,seg[l++]);
            if (r&1) rb = comb(seg[--r],rb);
        }
        return comb(ra,rb);
    }
};

signed main(){
    setIO();
    //CHECK FOR LONG LONG!!!    
    //LONG LONG OVERFLOW??
    int n, q; cin >> n >> q;
    Seg<int> st; 
    st.init(n);
    int a[n];
    for(int i = 0; i < n; ++i) {
        cin >> a[i];
        st.upd(i, a[i]);
    }
    while(q--) {
        int tp; cin >> tp;
        if(tp == 1){
            int x, y; cin >> x >> y; --x;
            st.upd(x, a[x]^y);
            a[x] ^= y;
        } else{
            int l, r; cin >> l >> r; --l; --r;
            cout << st.query(l, r)  << "\n";
        }
    }
    //CHECK FOR LONG LONG!!!
}
#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0;i<n;i++)
typedef long long ll;
const int mod = 1000000007;

struct mint {
  ll x; // typedef long long ll;
  mint(ll x=0):x((x%mod+mod)%mod){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;}
  mint operator+(const mint a) const { return mint(*this) += a;}
  mint operator-(const mint a) const { return mint(*this) -= a;}
  mint operator*(const mint a) const { return mint(*this) *= a;}
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }
  // for prime mod
  mint inv() const { return pow(mod-2);}
  mint& operator/=(const mint a) { return *this *= a.inv();}
  mint operator/(const mint a) const { return mint(*this) /= a;}
};
istream& operator>>(istream& is, const mint& a) { return is >> a.x;}
ostream& operator<<(ostream& os, const mint& a) { return os << a.x;}

mint all(ll n, ll a, ll b) {
  mint ax = n-a+1;
  mint bx = n-b+1;
  return ax*ax*bx*bx;
}
mint exclude(ll n, ll a, ll b) {
  mint ax = n-a+1; // N内にaの区間を置くパターン
  mint bx = n-b+1; // N内にbの区間を置くパターン
  mint x4 = a+b <= n ? (n-a-b+2)*(n-a-b+1)/2 : 0;
  mint x3 = x4*2;
  mint x2 = ax*bx-x3;
  return x2*x2;
}

int main() {
  int t; cin >> t;
  REP(i,t) {
    ll n,a,b; cin >> n >> a >> b;
    cout << all(n,a,b) - exclude(n,a,b) << endl;
  }
  return 0;
}