#include<bits/stdc++.h>
using namespace std;
const int N =5e4+10;
typedef long long ll;
int b[N],a[N];
int n,m;
struct node
{
int l,r;
int d[32];
void ins(int x)//插入
{
for(int i=31;i>=0;i--)
if(x>>i&1)
{
if(d[i]) x^=d[i];
else
{
d[i]=x;
break;
}
}
}
void ansins(node tree)
{
for(int i=31;i>=0;i--) ins(tree.d[i]);
}
}tr[N*4];
void pushup(int u)
{
node tmp;
tmp.l=tr[u].l,tmp.r=tr[u].r;
memset(tmp.d,0,sizeof tmp.d);
tmp.ansins(tr[u<<1]);
tmp.ansins(tr[u<<1|1]);
for(int i=31;i>=0;i--) tr[u].d[i]=tmp.d[i];
}
void build(int u, int l, int r)
{
tr[u].l=l,tr[u].r=r;
if(l==r)
{
tr[u].ins(a[r]);//这里注意
return;
}
int mid=l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
void modify(int u, int k,int x)
{
if(tr[u].l==tr[u].r)
{
memset(tr[u].d,0,sizeof tr[u].d);
tr[u].ins(a[tr[u].l]^x);
return;
}
int mid=tr[u].l+tr[u].r>>1;
if(k<=mid) modify(u<<1,k,x);
else modify(u<<1|1,k,x);
pushup(u);
}
node ans;
void query(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r)
{
ans.ansins(tr[u]);
return;
}
else
{
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid ) query(u << 1, l, r);
if (r > mid) query(u << 1 | 1, l, r);
}
}
struct BIT
{
void add(int x,int k){for(int i=x;i<=n;i+=i&-i) b[i]^=k;}
int Query(int x){int ans=0;for(int i=x;i;i-=i&-i) ans^=b[i]; return ans;}
}ruc;
int main()
{
scanf("%d%d", &n, &m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=n-1;i>=1;i--)
{
a[i+1]^=a[i];
//cout<<b[i]<<endl;
ruc.add(i+1,a[i+1]);
}
ruc.add(1,a[1]);
build(1,1,n);
while (m -- )
{
int opt,l,r;
int d;
scanf("%d%d%d%d", &opt, &l,&r,&d);
if(opt==1)
{
//cout<<l<<" "<<r<<" "<<d<<endl;
ruc.add(l,d);modify(1,l,d);
if(r<n)
{
ruc.add(r+1,d);
modify(1,r+1,d);
}
}
else
{
int res=d;
memset(ans.d,0,sizeof ans.d);
int tmp=ruc.Query(l);
ans.l=l,ans.r=r;
ans.ins(tmp);
if(l^r)
{
query(1,l+1,r);
for(int i=31;i>=0;i--)
if((res^ans.d[i])>res) res=res^ans.d[i];
cout<<res<<endl;
}
else
{
cout<<max(tmp^d,d)<<endl;
}
}
}
return 0;
}