//这道题比赛的时候不太会写,其实应该是(主席树+二分)
//找了一个模版,还有别人写的正解
https://blog.csdn.net/qq_37685156/article/details/80364092
https://blog.csdn.net/no_O_ac/article/details/97956068
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=1e5+100;
vector<int> v;
int n,m,a[maxn],rt[maxn],tot;
struct node
{
int l,r,sum;
}T[maxn*20];
int getid(int x)
{
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void build(int &o,int l,int r)
{
o=++tot;
T[o].sum=0;
if(l==r) return;
int mid=(l+r)>>1;
build(T[o].l,l,mid);
build(T[o].r,mid+1,r);
}
void update(int l,int r,int &now,int last,int k)
{
T[++tot]=T[last];
now=tot;
T[now].sum++;
if(l==r) return;
int mid=(l+r)>>1;
if(k<=mid) update(l,mid,T[now].l,T[last].l,k);
else update(mid+1,r,T[now].r,T[last].r,k);
}
int query(int l,int r,int x,int y,int k)
{
if(l==r) return T[y].sum-T[x].sum;
int mid=(l+r)>>1;
if(k<=mid) return query(l,mid,T[x].l,T[y].l,k);
else
{
int ret=0;
ret+=T[T[y].l].sum-T[T[x].l].sum;
ret+=query(mid+1,r,T[x].r,T[y].r,k);
return ret;
}
}
int solve(int ll,int rr,int p,int kth)
{
int l = 0,r = maxn * 10;
int ans = r;
while(l <= r)
{
int mid = (l + r) >> 1;
int lef = p - mid,rig = p + mid;
int l1,r1;
int k1=upper_bound(v.begin(),v.end(),lef-1)-v.begin();
if(!k1) l1=0;
else
l1=query(1,n,rt[ll-1],rt[rr],k1);
int k2=upper_bound(v.begin(),v.end(),rig)-v.begin();
if(!k2) r1=0;
else
r1=query(1,n,rt[ll-1],rt[rr],k2);
if(r1-l1>=kth)
{
r = mid - 1;
ans = min(ans,mid);
}
else
l = mid + 1;
}
printf("%d\n",ans);
return ans;
}
int main()
{
int t;
scanf("%d",&t);
for(int kase=1;kase<=t;kase++)
{
v.clear();
tot=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),v.push_back(a[i]);
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
build(rt[0],1,n);
for(int i=1;i<=n;i++)
update(1,n,rt[i],rt[i-1],getid(a[i]));
int l,r,p,k;
int x=0;
while(m --)
{
scanf("%d%d%d%d",&l,&r,&p,&k);
l ^= x; r ^= x; p ^= x; k ^= x;
x = solve(l,r,p,k);
}
}
return 0;
}