#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define N 300000
using namespace std;
int read()
{
char c=0;
int sum=0;
while (c<'0'||c>'9') c=getchar();
while ('0'<=c&&c<='9') sum=sum*10+c-'0',c=getchar();
return sum;
}
const int inf=(int)(1e9);
struct reads
{
int num,data;
bool operator < (const reads &t)const
{
return data<t.data;
}
};
reads tong[N+1];
struct rds
{
int num,data,data2;
bool operator < (const rds &t)const
{
return data!=t.data?data<t.data:data2<t.data2;
}
};
rds tongs[N+1];
int n,m,q,ans,length,lg[N+1],rt[N+1],rt2[N+1],st[N+1],lengs,dque[N+1],top,dfn[N+1],sz[N+1],len,v1[N+1],v2[N+1],fa[N+1],fa2[N+1][21],depth[N+1],depth2[N+1],ST[N+1][21];
bool used[N+1],used2[N+1];
vector<int>E[N+1];
vector<int>E2[N+1];
set<reads>s[N+1];
void add(int x,int y)
{
E[x].push_back(y),E[y].push_back(x);
return;
}
void add2(int x,int y)
{
E2[x].push_back(y),E2[y].push_back(x);
return;
}
void dfs(int x)
{
used[x]=1;
for (int i=0;i<E[x].size();++i)
if (!used[E[x][i]])
fa[E[x][i]]=x,depth[E[x][i]]=depth[x]+1,dfs(E[x][i]);
return;
}
void dfs2(int x)
{
dfn[x]=++len,used2[x]=sz[x]=1;
for (int i=0;i<E2[x].size();++i)
if (!used2[E2[x][i]])
fa2[E2[x][i]][0]=x,depth2[E2[x][i]]=depth2[x]+1,dfs2(E2[x][i]),sz[x]+=sz[E2[x][i]];
return;
}
bool cmp(int x,int y)
{
return depth[x]<depth[y];
}
int lca(int x,int y)
{
if (depth2[x]<depth2[y]) swap(x,y);
for (int i=lg[m];i>=0;--i)
if (depth2[fa2[x][i]]>=depth2[y])
x=fa2[x][i];
if (x==y) return x;
for (int i=lg[m];i>=0;--i)
if (fa2[x][i]!=fa2[y][i])
x=fa2[x][i],y=fa2[y][i];
return fa2[x][0];
}
void dfs3(int x,int d)
{
if (depth[x]<=d) dque[++top]=v1[x];
for (int i=0;i<E[x].size();++i)
if (fa[E[x][i]]==x)
dfs3(E[x][i],d);
return;
}
struct seg
{
struct node
{
int ls,rs,data;
};
node tree[100*N+1];
void push_up(int k)
{
tree[k].data=tree[tree[k].ls].data+tree[tree[k].rs].data;
return;
}
int add(int k,int L,int R,int x,int d)
{
int nw=++length;
tree[nw]=tree[k];
if (L==R)
{
tree[nw].data+=d;
return nw;
}
int mid=(L+R)>>1;
if (x<=mid) tree[nw].ls=add(tree[nw].ls,L,mid,x,d);
else tree[nw].rs=add(tree[nw].rs,mid+1,R,x,d);
push_up(nw);
return nw;
}
int query(int k,int L,int R,int l,int r)
{
if (L==l&&R==r) return tree[k].data;
int mid=(L+R)>>1;
if (r<=mid) return query(tree[k].ls,L,mid,l,r);
else if (l>=mid+1) return query(tree[k].rs,mid+1,R,l,r);
else return query(tree[k].ls,L,mid,l,mid)+query(tree[k].rs,mid+1,R,mid+1,r);
}
};
seg T;
int get_query(int l,int r)
{
if (l>r) return inf;
int lw=lg[r-l+1];
return min(ST[l][lw],ST[r-(1<<lw)+1][lw]);
}
int main()
{
int op,x,y,d,d1,d2,ps,l,r,pv,nt;
for (int i=2;i<=N;++i) lg[i]=lg[i>>1]+1;
n=read(),m=read(),q=read();
for (int i=1;i<=n-1;++i) x=read(),y=read(),add(x,y);
for (int i=1;i<=m-1;++i) x=read(),y=read(),add2(x,y);
for (int i=1;i<=n;++i) v1[i]=read();
for (int i=1;i<=m;++i) v2[i]=read(),st[++lengs]=v2[i];
sort(st+1,st+lengs+1),lengs=unique(st+1,st+lengs+1)-st-1,depth[1]=depth2[1]=1,dfs(1),dfs2(1);
for (int i=1;i<=m;++i) tong[i]=(reads){i,depth2[i]};
sort(tong+1,tong+m+1);
for (int i=1;i<=lg[m];++i)
for (int j=1;j<=m;++j)
fa2[j][i]=fa2[fa2[j][i-1]][i-1];
for (int i=1;i<=m;++i)
{
int d=lower_bound(st+1,st+lengs+1,v2[tong[i].num])-st;
auto it=s[d].lower_bound((reads){tong[i].num,dfn[tong[i].num]});
rt[i]=T.add(rt[i-1],1,m,dfn[tong[i].num],1);
if (it!=s[d].end()) nt=(*it).num;
else nt=-1;
if (it!=s[d].begin()) it--,pv=(*it).num;
else pv=-1;
if (pv!=-1) rt[i]=T.add(rt[i],1,m,dfn[lca(pv,tong[i].num)],-1);
if (nt!=-1) rt[i]=T.add(rt[i],1,m,dfn[lca(nt,tong[i].num)],-1);
if (pv!=-1&&nt!=-1) rt[i]=T.add(rt[i],1,m,dfn[lca(pv,nt)],1);
s[d].insert((reads){tong[i].num,dfn[tong[i].num]});
}
for (int i=1;i<=m;++i) tongs[i]=(rds){i,lower_bound(st+1,st+lengs+1,v2[i])-st,dfn[i],depth2[i]};
sort(tongs+1,tongs+m+1);
for (int i=1;i<=m;++i) ST[i][0]=depth[tongs[i].num];
for (int i=1;i<=lg[m];++i)
for (int j=1;j<=m;++j)
ST[j][i]=min(ST[j][i-1],ST[j+(1<<(i-1))][i-1]);
while (q--)
{
op=read();
if (op==1)
{
x=read(),y=read(),d1=read()^ans,d2=read()^ans,ps=lower_bound(tong+1,tong+m+1,(reads){0,depth2[y]+d2+1})-tong-1,ans=T.query(rt[ps],1,m,dfn[y],dfn[y]+sz[y]-1),top=0,dfs3(x,depth[x]+d1),sort(dque+1,dque+top+1),top=unique(dque+1,dque+top+1)-dque-1;
for (int i=1;i<=top;++i)
{
if (st[lower_bound(st+1,st+lengs+1,dque[i])-st]==dque[i]) d=lower_bound(st+1,st+lengs+1,dque[i])-st,l=lower_bound(tongs+1,tongs+m+1,(rds){0,d,dfn[y]})-tongs,r=lower_bound(tongs+1,tongs+m+1,(rds){0,d,dfn[y]+sz[y]})-tongs-1,ans+=(get_query(l,r)>depth2[y]+d2);
else ans++;
}
printf("%d\n",ans);
}
else x=read(),d=read(),v1[x]=d;
}
return 0;
}