#include <bits/stdc++.h>
using namespace std;
using ll = uint64_t;
#define rep(i, n) for(ll i = 0; i < (n); ++i)
#define rep2(i, l, r) for(ll i = (l); i < (r); ++i)
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
#define all(A) A.begin(), A.end()
#define elif else if
using pii = pair<ll, ll>;
bool chmin(auto &a, auto b) {return a > b ? a = b, 1 : 0;}
bool chmax(auto &a, auto b) {return a < b ? a = b, 1 : 0;}
struct IOS {
IOS() {
cin.tie(0);
ios::sync_with_stdio(0);
}
} iosetup;
template<class T>
void print(vector<T> a) {
for(auto x : a) cout << x << ' ';
cout << endl;
}
void print(auto x) {
cout << x << endl;
}
template<class Head, class... Tail>
void print(Head &&head, Tail &&...tail) {
cout << head << ' ';
print(forward<Tail>(tail)...);
}
template<class S, S (*op) (S, S), S (*e)()>
struct segtree {
int sz, N;
vector<S> d;
segtree() = default;
segtree(int n) : segtree(vector<S>(n, e())) {}
segtree(const vector<S> &v) {
sz = 1;
N = v.size();
while(sz < N) sz <<= 1;
d.assign(2 * sz, e());
rep(i, N) d[i+sz] = v[i];
for(int k = sz - 1; k > 0; k--) d[k] = op(d[2*k], d[2*k+1]);
}
void set(int k, S x) {
k += sz;
d[k] = x;
while(k >>= 1) d[k] = op(d[2*k], d[2*k+1]);
}
S prod(int l, int r) {
S sml = e(), smr = e();
for(l += sz, r += sz; l < r; l >>= 1, r >>= 1) {
if(l&1) sml = op(sml, d[l++]);
if(r & 1) smr = op(d[--r], smr);
}
return op(sml, smr);
}
S get(int k) {return d[k+sz];}
template<typename C>
int max_right(int l, const C &check) {
if(l == N) return N;
l += sz;
S sm = e();
do {
while(l % 2 == 0) l >>= 1;
if(!check(op(sm, d[l]))) {
while(l < sz) {
l *= 2;
if(check(op(sm, d[l]))) {
sm = op(sm, d[l]);
l++;
}
}
return l - sz;
}
sm = op(sm, d[l]);
l++;
} while((l & -l) != l);
return N;
}
};
using S=array<ll,3>;
ll mask=9223372036854775807LL; // (1<<63)-1
S op(S L,S R){
return {L[0]&R[0],(L[0]&R[1])^(R[0]&L[1]),L[2]+R[2]};
}
S e(){return {mask,0,0};}
ll op2(ll L,ll R){return L|R;}
ll e2(){return 0;}
int main(){
int n,q;
cin>>n>>q;
vll a(n);
rep(i,n)cin>>a[i];
vector<S>init(n);
rep(i,n){
init[i]={a[i],a[i]^mask,1};
}
segtree<S,op,e>seg1(init);
segtree<ll,op2,e2>seg2(a);
while(q--){
int t;
cin>>t;
if(t==1){
int l,r;
ll x;
cin>>l>>r>>x;
l--;
ll res=x^mask;
auto check=[&](ll y)->bool{
return (y&res)==0;
};
while(true){
int p=seg2.max_right(l,check);
if(p<r){
a[p]&=x;
seg1.set(p,{a[p],a[p]^mask,1});
seg2.set(p,a[p]);
}
else break;
}
print(a);
}
if(t==2){
int s;
ll x;
cin>>s>>x;
seg1.set(s-1,{x,x^mask,1});
seg2.set(s-1,x);
a[s-1]=x;
print(a);
}
if(t==3){
int l,r;
cin>>l>>r;
l--;
S val=seg1.prod(l,r);
if(val[1]==0){
cout<<val[0]<<'\n';
}
else{
ll top=__bit_floor(val[1]);
// assert(top!=-1);
auto check=[&](S x)->bool{
return ((x[0]>>top)&1)==1;
};
int mid=seg1.max_right(l,check);
ll ans=seg1.prod(l,mid)[0]&seg1.prod(mid+1,r)[0];
cout<<ans<<'\n';
}
}
}
}
a