#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<unordered_map>
#include<vector>
#include<bitset>
#include<queue>
#include<set>
#include<map>
#include<ctime>
#include<random>
#include<numeric>
using namespace std;
#define int long long
#define ll long long
#define ull unsigned long long
#define lc (x<<1)
#define rc (x<<1|1)
#define pii pair<int,int>
#define mkp make_pair
#define fi first
#define se second
#define cout (cerr<<">> ",cout)
const int Mx=500005,p=998244353;
int read(){
char ch=getchar();
int Alice=0,Aya=1;
while(ch<'0'||ch>'9'){
if(ch=='-') Aya=-Aya;
ch=getchar();
}
while(ch>='0'&&ch<='9')
Alice=(Alice<<3)+(Alice<<1)+(ch^48),ch=getchar();
return (Aya==1?Alice:-Alice);
}
int n,m;
int val[Mx],col[Mx];
unordered_map<int,int>hv;
//(node,col)
//node*10^6+col
int Hash(int id,int c){
return 1000000ll*id+c;
}
class SegTree{
private:
struct Node{
int l,r;
int sum;
};
Node t[Mx<<2];
void PushUp(int x){
t[x].sum=t[lc].sum+t[rc].sum;
}
public:
void Build(int x,int l,int r){
t[x].l=l,t[x].r=r;
t[x].sum=0;
for(int o=l;o<=r;o++) hv[Hash(x,col[o])]++;
if(l==r){
t[x].sum=val[l];
return;
}
int mid=((l+r)>>1);
Build(lc,l,mid),Build(rc,mid+1,r);
PushUp(x);
}
int QryL(int x,int R,const vector<int>&C,bool z){
int l=t[x].l,r=t[x].r;
//cout<<x<<" : "<<l<<" "<<r<<" : "<<R<<endl;
bool ok=1;
if(z&&r==R){
int cnt=0;
for(int c:C){
cnt+=hv[Hash(x,c)];
}
if(cnt==r-l+1) return l;
ok=0;
}
if(l==r) return -1;
int mid=((l+r)>>1);
if(R>mid){
int res=QryL(rc,R,C,1);
if(res==mid+1){
int ser=QryL(lc,mid,C,ok);
if(ser!=-1) return ser;
else return res;
}
else return res;
}
else{
return QryL(lc,R,C,1);
}
}
int QryR(int x,int L,const vector<int>&C,bool z){
int l=t[x].l,r=t[x].r;
bool ok=1;
if(z&&l==L){
int cnt=0;
for(int c:C){
cnt+=hv[Hash(x,c)];
}
if(cnt==r-l+1) return r;
ok=0;
}
if(l==r) return -1;
int mid=((l+r)>>1);
if(L<=mid){
int res=QryR(lc,L,C,1);
if(res==mid){
int ser=QryR(rc,mid+1,C,ok);
if(ser!=-1) return ser;
else return res;
}
else return res;
}
else{
return QryR(rc,L,C,1);
}
}
int QrySum(int x,int L,int R){
int l=t[x].l,r=t[x].r;
if(l==L&&r==R){
return t[x].sum;
}
int mid=((l+r)>>1);
if(L>mid) return QrySum(rc,L,R);
else if(R<=mid) return QrySum(lc,L,R);
else return QrySum(lc,L,mid)+QrySum(rc,mid+1,R);
}
void ModifyVal(int x,int id,int k){
int l=t[x].l,r=t[x].r;
if(l==r){
t[x].sum=k;
return;
}
int mid=((l+r)>>1);
if(id>mid) ModifyVal(rc,id,k);
else ModifyVal(lc,id,k);
PushUp(x);
}
void ModifyCol(int x,int id,int c,int k){
int l=t[x].l,r=t[x].r;
hv[Hash(x,c)]+=k;
if(l==r) return;
int mid=((l+r)>>1);
if(id>mid) ModifyCol(rc,id,c,k);
else ModifyCol(lc,id,c,k);
}
}tr;
void Solve(){
hv.clear();
n=read(),m=read();
for(int i=1;i<=n;i++) col[i]=read();
for(int i=1;i<=n;i++) val[i]=read();
tr.Build(1,1,n);
int mx=0;
for(int Id=1,op,x,y;Id<=m;Id++){
op=read(),x=read(),y=read();
if(op==1){
tr.ModifyCol(1,x,col[x],-1);
col[x]=y;
tr.ModifyCol(1,x,col[x],1);
}
else if(op==2){
val[x]=y;
tr.ModifyVal(1,x,val[x]);
}
else{
vector<int>o(y);
for(int &_:o) _=read();
tot=0;
int l=tr.QryL(1,x,o,1),r=tr.QryR(1,x,o,1);
mx=max(mx,tot);
printf("%lld\n",tr.QrySum(1,l,r));
}
}
}
signed main(){
int T=read();
while(T--) Solve();
return 0;
}
/*
Hello!!
Sample:
1
8 1
2 9 4 1 3 4 5 5
53074607 20450313 38863273 86320988 58620690 49800409 56301817 32928383
3 7 6 5 1 3 4 9 10
-------------------
*/