#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<pii> vii;
typedef vector<int> vi;
const int inf=0x3f;
const int N=1e5+10;
ll n,m;
ll p[N],q[N],c[N];
int lowbit(int x) {
return x&(-x);
}
void add(ll x,ll d) {
for(int i=x;i<=n;i+=lowbit(i)) c[i]+=d;
}
ll qry(ll x) {
ll res=0;
for(int i=x;i>=1;i-=lowbit(i)) res+=c[i];
return res;
}
ll ls[2][N],mp[N];
ll Tr[2][N<<4],up[2][N<<4];//两棵,区间赋值,区间求和
void build(int rt,int l,int r,int op)
{
if(l==r)
{
Tr[op][rt]=ls[op][l];
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid,op);
build(rt<<1|1,mid+1,r,op);
Tr[op][rt]=Tr[op][rt<<1]+Tr[op][rt<<1|1];
}
void push_down(int rt,int l,int r,int op)
{
if(up[op][rt])
{
ll mid=(l+r)>>1;
Tr[op][rt<<1]=up[op][rt]*(mid-l+1);
Tr[op][rt<<1|1]=up[op][rt]*(r-mid);
up[op][rt<<1]=up[op][rt];
up[op][rt<<1|1]=up[op][rt];
up[op][rt]=0;
}
}
void update(int rt,int l,int r,int x,int y,ll val,int op)//将 [x,y] 内的数赋值成 val
{
if(up[op][rt]) push_down(rt,l,r,op);
if(x<=l&&r<=y)
{
Tr[op][rt]=val*(r-l+1);
up[op][rt]=val;
return ;
}
int mid=(l+r)>>1;
if(x<=mid) update(rt<<1,l,mid,x,y,val,op);
if(y>mid) update(rt<<1|1,mid+1,r,x,y,val,op);
Tr[op][rt]=Tr[op][rt<<1]+Tr[op][rt<<1|1];
}
ll query(int rt,int l,int r,int x,int y,int op)//求[x,y]的和
{
if(up[op][rt]) push_down(rt,l,r,op);
if(x<=l&&r<=y) return Tr[op][rt];
ll mid=(l+r)>>1,sum=0;
if(x<=mid) sum+=query(rt<<1,l,mid,x,y,op);
if(y>mid) sum+=query(rt<<1|1,mid+1,r,x,y,op);
return sum;
}
void upd(int x,int y) {
p[x]=y;
if(n==1) return;
if(x==1) {
if(p[x]==p[x+1]) {
int y1=query(1,1,n,x+1,x+1,1);
if(x+1==n) y1=n+1;
update(1,1,n,x,x,y1,1);//变点的右边
update(1,1,n,x+1,y1-1,0,0);//变点右边区间的左边
}
else {
int y1=query(1,1,n,x+1,x+1,1);
if(x+1==n) y1=n+1;
update(1,1,n,x,x,x+1,1);//变点的右边
update(1,1,n,x+1,y1-1,x,0);//变点右边区间的左边
}
}
else if(x==n) {
if(p[x]==p[x-1]) {
int x1=query(1,1,n,x-1,x-1,0);
if(x-1==1) x1=0;
update(1,1,n,x,x,x1,0);//变点的左边
update(1,1,n,x1+1,x-1,x+1,1);//变点左边区间的右边
}
else {
int x1=query(1,1,n,x-1,x-1,0);
if(x-1==1) x1=0;
update(1,1,n,x,x,x-1,0);//变点的左边
update(1,1,n,x1+1,x-1,x,1);//变点左边区间的右边
}
}
else if(p[x]!=p[x-1]&&p[x]!=p[x+1]) {
int y1=query(1,1,n,x+1,x+1,1);
int x1=query(1,1,n,x-1,x-1,0);
update(1,1,n,x1+1,x-1,x,1);
update(1,1,n,x+1,y1-1,x,0);
update(1,1,n,x,x,x-1,0);
update(1,1,n,x,x,x+1,1);
}
else if(p[x]==p[x-1]&&p[x]==p[x+1]) {
int y1=query(1,1,n,x+1,x+1,1);
int x1=query(1,1,n,x-1,x-1,0);
update(1,1,n,x1+1,x-1,y1,1);
update(1,1,n,x+1,y1-1,x1,0);
update(1,1,n,x,x,x1,0);
update(1,1,n,x,x,y1,1);
}
else if(p[x]==p[x-1]) {
int y1=query(1,1,n,x+1,x+1,1);
int x1=query(1,1,n,x-1,x-1,0);
update(1,1,n,x1+1,x-1,x+1,1);
update(1,1,n,x+1,y1-1,x,0);
update(1,1,n,x,x,x1,0);
update(1,1,n,x,x,x+1,1);
}
else if(p[x]==p[x+1]) {
int y1=query(1,1,n,x+1,x+1,1);
int x1=query(1,1,n,x-1,x-1,0);
update(1,1,n,x1+1,x-1,x,1);
update(1,1,n,x+1,y1-1,x-1,0);
update(1,1,n,x,x,x-1,0);
update(1,1,n,x,x,y1,1);
}
}
void init() {
for(int i=0;i<=n+1;i++) {
c[i]=p[i]=q[i]=0;
ls[0][i]=ls[1][i]=0;
}
for(int i=0;i<=(n<<4)+5;i++) {
Tr[0][i]=Tr[1][i]=0;
up[0][i]=up[1][i]=0;
}
}
void get_ls() {
for(int i=1;i<=n;i++) {
if(i==1||p[i]!=p[i-1]) ls[0][i]=i-1;
else ls[0][i]=ls[0][i-1];
}
for(int i=n;i>=1;i--) {
if(i==n||p[i]!=p[i+1]) ls[1][i]=i+1;
else ls[1][i]=ls[1][i+1];
}
}
void print() {
for(int i=1;i<=n;i++) cout<<p[i]<<' ';
cout<<endl;
for(int i=1;i<=n;i++) cout<<query(1,1,n,i,i,0)<<' ';
cout<<endl;
for(int i=1;i<=n;i++) cout<<query(1,1,n,i,i,1)<<' ';
cout<<endl;
}
signed main() {
IOS
int t;
cin>>t;
vi ans;
int sz=0;
while(t--) {
cin>>n>>m;
init();
for(int i=1;i<=n;i++) cin>>p[i];
for(int i=1;i<=n;i++) {
cin>>q[i]; add(i,q[i]);
}
get_ls();
build(1,1,n,0);
build(1,1,n,1);
while(m--) {
int op; cin>>op;
if(op==2) {
int x,y; cin>>x>>y;
add(x,-q[x]);
add(x,y); q[x]=y;
}
else if(op==1) {
int x,y; cin>>x>>y;
upd(x,y);
}
else if(op==3) {
vi g;
int now,k; cin>>now>>k;
for(int i=1;i<=k;i++) {
int x; cin>>x;
g.push_back(x); mp[x]=1;
}
int l=now,r=now;
while(l&&mp[p[l]]) l=query(1,1,n,l,l,0); l++;
while(r<=n&&mp[p[r]]) r=query(1,1,n,r,r,1); r--;
// cout<<qry(r)-qry(l-1)<<'\n';
ans.push_back(qry(r)-qry(l-1));
if(++sz<=193) {
get_ls();
int pd=0;
for(int i=1;i<=n&&!pd;i++) {
if(l[0][i]!=query(1,1,n,i,i,0)) pd=1;
if(l[1][i]!=query(1,1,n,i,i,1)) pd=1;
}
if(pd) print();
if(pd) break;
}
else break;
for(auto i:g) mp[i]=0;
}
}
}
for(auto i:ans) cout<<i<<endl;
return 0;
}