/*
前缀线性基
对于每个线性基中的每一位尽量取靠右的数字作为当前位
故维护时需要维护每一位的位置
每次查询只需查找lb[r]中从高到低找到当前位的位置是否大于查询的l
*/
#include
using namespace std;
typedef long long LL;
const int N = 1e6+10;
struct Linear_Basis{
int d[31];
int pos[31];
int cnt;
bool zero;
Linear_Basis(){
memset(d,0,sizeof(d));
memset(pos,0,sizeof(pos));
cnt=0; zero=0;
}
void init(){
memset(d,0,sizeof(d));
memset(pos,0,sizeof(pos));
cnt=0; zero=0;
}
void insert(int val,int pp){ //插入时更新
for(int i=30;i>=0;i--){
if(val&(1<pos[i]){
int tv=d[i];
int tp=pos[i];
d[i]=val;
pos[i]=pp;
val=tv;
pp=tp;
}
val^=d[i];
}
}
}
int query_ans(int l){
int res=0;
for(int i=30;i>=0;i--){
if(pos[i]>=l)res=max(res,res^d[i]);
}
return res;
}
}lb[N];
int n,m;
int main() {
#ifdef ACM_LOCAL
freopen("./std.in","r",stdin);
#endif
int T;
int ex = 0;
scanf("%d", &T);
while (T--) {
scanf("%d%d",&n,&m);
int lastans=0;
for(int i=1;i<=n;i++){
int t;
scanf("%d",&t);
lb[i].init();
lb[i]=lb[i-1];
lb[i].insert(t,i);
}
while(m--){
int op;
scanf("%d",&op);
if(op==0){
int l,r;
scanf("%d%d",&l,&r);
l=(l^lastans)%n+1;
r=(r^lastans)%n+1;
if(l>r)swap(l,r);
lastans=lb[r].query_ans(l);
printf("%d\n",lastans);
}
else if(op==1){
int x;
scanf("%d",&x);
x=x^lastans;
lb[n+1].init();
lb[n+1]=lb[n];
lb[n+1].insert(x,n+1);
n++;
}
}
}
}