#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pld;
typedef vector<ll> vll;
typedef vector<ld> vld;
typedef vector<pll> vpll;
typedef vector<pld> vpld;
#define int ll
#define all(it) it.begin(),it.end()
#define ord_set(T) tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>
const int MOD = 1000000007;
struct SegmentTree{
vector<vector<array<int,2>>> tree;
int n;
SegmentTree(int n) : n(n) {
int size = 1 << (int) (log2(n)+1);
tree.resize(2*size-1,vector<array<int,2>>(21,{0,0}));
}
private:
vector<array<int,2>> merge(vector<array<int,2>> l, vector<array<int,2>> r){
vector<array<int,2>> res(21,{0,0});
for (int i=0;i<21;i++){
res[i][0] = (l[i][0] + r[i][0] + l[i][0] * r[i][0] % MOD + l[i][1] * r[i][1] % MOD)%MOD;
res[i][1] = (l[i][1] + r[i][1] + l[i][0] * r[i][1] % MOD + l[i][1] * r[i][0] % MOD)%MOD;
}
return res;
}
void insert(int v, int ind, int l, int r, int i=0){
if (l == r && ind == l){
for (int j=0;j<21;j++){
if ((1 << j) & v) tree[i][j][1] = 1, tree[i][j][0] = 0;
else tree[i][j][0] = 1, tree[i][j][1] = 0;
}
return;
}
if (l > ind) return;
if (r < ind) return;
int mid = (l+r)/2;
insert(v,ind,l,mid,i*2+1);
insert(v,ind,mid+1,r,i*2+2);
// merge results
tree[i] = merge(tree[i*2+1],tree[i*2+2]);
}
vector<array<int,2>> query(int l, int r, int cl, int cr, int i){
if (l <= cl && r >= cr) return tree[i];
if (cl > r || cr < l) return vector<array<int,2>>(21,{0,0}); // neutral element
int mid = (cl+cr)/2;
// merge results
return merge(query(l,r,cl,mid,i*2+1), query(l,r,mid+1,cr,i*2+2));
}
public:
void insert(int ind, int v) { insert(v,ind,0,n); }
vector<array<int,2>> query(int l, int r) { return query(l,r,0,n,0); }
};
void work(){
int n,q;
cin >> n >> q;
vll v(n);
for (auto &c : v) cin >> c;
SegmentTree st(n);
for (int i=0;i<n;i++) st.insert(i,v[i]);
for (int i=0;i<q;i++){
int t,a,b;
cin >> t >> a >> b;
if (t == 1){
v[--a] ^= b;
st.insert(a,v[a]);
}else{
auto q = st.query(a-1,b-1);
int res = 0;
for (int i=0;i<21;i++) res = (res + (1 << i) * q[i][1] % MOD)%MOD;
cout << res << '\n';
}
}
}
int32_t main(){
cin.tie(NULL);
ios_base::sync_with_stdio(false);
work();
return 0;
}