#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int N=4e5+5;
const int M=4e7+5;
struct node
{
int size,l,r;
}tr[M];
int n,m,q,K;
int tot,fst[N],nxt[N*2],go[N*2],f[N],p[N],root[N*4],loc[N*4],cnt,sum[N*4],temp,que[N*4];
int father[N],deep[N],son[N],size[N],pos[N],idx[N],top[N];
inline int R()
{
char c;int f=0;
for(c=getchar();c<‘0‘||c>‘9‘;c=getchar());
for(;c<=‘9‘&&c>=‘0‘;c=getchar())
f=(f<<3)+(f<<1)+c-‘0‘;
return f;
}
inline void comb(int a,int b)
{
nxt[++tot]=fst[a],fst[a]=tot,go[tot]=b;
nxt[++tot]=fst[b],fst[b]=tot,go[tot]=a;
}
inline void dfs1(int u)
{
size[u]=1;
for(int e=fst[u];e;e=nxt[e])
{
int v=go[e];if(v==father[u]) continue;
father[v]=u;deep[v]=deep[u]+1;
dfs1(v);size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
}
inline void dfs2(int u)
{
if(son[u])
{
idx[pos[son[u]]=++tot]=son[u];
top[son[u]]=top[u];dfs2(son[u]);
}
for(int e=fst[u];e;e=nxt[e])
{
int v=go[e];if(v==father[u]||v==son[u]) continue;
idx[pos[v]=++tot]=v;
top[v]=v;dfs2(v);
}
}
inline void pre()
{
dfs1(1);
tot=pos[1]=idx[1]=top[1]=1;
dfs2(1);
}
inline void modify2(int &k,int l,int r,int v)
{
if(!k) k=++tot;tr[k].size++;
if(l==r) return;
int mid=(l+r)/2;
if(v<=mid) modify2(tr[k].l,l,mid,v);
else modify2(tr[k].r,mid+1,r,v);
}
inline void delete2(int k,int l,int r,int v)
{
tr[k].size--;
if(l==r) return;
int mid=(l+r)/2;
if(v<=mid) delete2(tr[k].l,l,mid,v);
else delete2(tr[k].r,mid+1,r,v);
}
inline void modify1(int k,int l,int r,int p,int v)
{
sum[k]++;
modify2(root[k],1,1000,v);
if(l==r) return;
int mid=(l+r)/2;
if(p<=mid) modify1(k*2,l,mid,p,v);
else modify1(k*2+1,mid+1,r,p,v);
}
inline void delete1(int k,int l,int r,int p,int v)
{
sum[k]--;
delete2(root[k],1,1000,v);
if(l==r) return;
int mid=(l+r)/2;
if(p<=mid) delete1(k*2,l,mid,p,v);
else delete1(k*2+1,mid+1,r,p,v);
}
inline void getroot2(int k,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
{
que[++cnt]=root[k];temp+=sum[k];
return;
}
int mid=(l+r)/2;
if(x<=mid) getroot2(k*2,l,mid,x,y);
if(y>mid) getroot2(k*2+1,mid+1,r,x,y);
}
inline void getroot1(int a,int b)
{
if(top[a]!=top[b])
{
if(deep[top[a]]<deep[top[b]]) swap(a,b);
getroot2(1,1,n,pos[top[a]],pos[a]);
getroot1(father[top[a]],b);
}
else
{
if(deep[a]<deep[b]) swap(a,b);
getroot2(1,1,n,pos[b],pos[a]);
}
}
inline int calc()
{
int t=0;
for(int i=1;i<=cnt;i++) t+=tr[tr[loc[i]].l].size;
return t;
}
inline void trans(int op)
{
if(!op)
for(int i=1;i<=cnt;i++) loc[i]=tr[loc[i]].l;
else
for(int i=1;i<=cnt;i++) loc[i]=tr[loc[i]].r;
}
inline int query(int l,int r,int k)
{
if(l==r) return l;
int t=calc();int mid=(l+r)/2;
if(t>=k)
{
trans(0);
return query(l,mid,k);
}
else
{
trans(1);
return query(mid+1,r,k-t);
}
}
int main()
{
n=R();int a,b,op;
for(int i=1;i<n;i++)
{
a=R(),b=R();
comb(a,b);
}
pre();
m=R();tot=0;
for(int i=1;i<=m;i++)
{
f[i]=R(),p[i]=R();
modify1(1,1,n,pos[p[i]],f[i]);
}
q=R(),K=R();
while(q--)
{
op=R(),a=R(),b=R();
if(op==1)
{
temp=cnt=0;
getroot1(a,b);
if(!temp) printf("-1");
if(temp<=K)
{
for(int i=temp;i>=1;i--)
{
for(int j=1;j<=cnt;j++) loc[j]=que[j];
printf("%d ",query(1,1000,i));
}
}
else
{
for(int i=temp;i>=temp-K+1;i--)
{
for(int j=1;j<=cnt;j++) loc[j]=que[j];
printf("%d ",query(1,1000,i));
}
}
printf("\n");
}
else if(op==2)
{
delete1(1,1,n,pos[p[a]],f[a]);
p[a]=b;
modify1(1,1,n,pos[p[a]],f[a]);
}
else if(op==3)
{
delete1(1,1,n,pos[p[a]],f[a]);
f[a]=b;
modify1(1,1,n,pos[p[a]],f[a]);
}
}
}