#include <bits/stdc++.h>
#define int long long
#define ls(x) ((x) << 1)
#define rs(x) ((x) << 1 | 1)
using namespace std;
const int N = 6e4 + 10;
int n, m, q, k, f[N], p[N], dfn[N], dpt[N], fa[N], siz[N], top[N], son[N], num;
vector <int> a[N];
struct node {
int l, r;
map <int, int> p;
};
node t[4 * N];
void push_up (int p) {
t[p].p = t[ls(p)].p;
for (auto i : t[rs(p)].p)
t[p].p[i.first] += i.second;
return;
}
void build (int l, int r, int p) {
t[p].l = l, t[p].r = r;
if (l == r) {
return;
}
int mid = (l + r) >> 1;
build (1, mid, ls(p));
build (mid + 1, r, rs(p));
push_up(p);
return;
}
void update (int x, int p, int d) {
if (t[p].l == t[p].r) {
-- t[p].p[d];
if (t[p].p[d] <= 0) t[p].p.erase(d);
return;
}
int mid = (t[p].l + t[p].r) >> 1;
if (x <= mid) update (x, ls(p), d);
else update (x, rs(p), d);
push_up(p);
return;
}
vector <int> v;
void modify (int x, int p, int d) {
if (t[p].l == t[p].r) {
++ t[p].p[d];
return;
}
int mid = (t[p].l + t[p].r) >> 1;
if (x <= mid) modify (x, ls(p), d);
else modify (x, rs(p), d);
push_up(p);
return;
}
void upd (int x, int p, int d1, int d2) {
if (t[p].l == t[p].r) {
-- t[p].p[d1];
if (t[p].p[d1] <= 0) t[p].p.erase(d1);
++ t[p].p[d2];
return;
}
int mid = (t[p].l + t[p].r) >> 1;
if (x <= mid) upd (x, ls(p), d1, d2);
else upd (x, rs(p), d1, d2);
push_up(p);
return;
}
void query1 (int l, int r, int p) {
if (l <= t[p].l && t[p].r <= r) {
int cnt = k;
if (!t[p].p.size()) return;
for (map <int, int> :: iterator it = t[p].p.end(); it != t[p].p.begin(); ) {
-- it;
if (cnt - it->second >= 0) {
for (int j = 1; j <= it->second; ++ j ) v.push_back(it->first);
cnt -= it->second;
} else {
for (int j = 1; j <= cnt; ++ j ) v.push_back(it->first);
break;
}
}
return;
}
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) query1 (l, r, ls(p));
if (r > mid) query1 (l, r, rs(p));
return;
}
void dfs1 (int u, int f) {
dpt[u] = dpt[f] + 1;
fa[u] = f;
siz[u] = 1;
int maxn = 0;
for (int v : a[u]) {
if (v == f) continue;
dfs1 (v, u);
if (siz[v] > maxn) {
maxn = siz[v];
son[u] = v;
}
siz[u] += siz[v];
}
return;
}
void dfs2 (int u, int f) {
dfn[u] = ++ num;
top[u] = f;
if (son[u]) dfs2 (son[u], f);
for (int v : a[u]) {
if (v == fa[u] || v == son[u]) continue;
dfs2 (v, v);
}
return;
}
void que (int u, int v) {
::v.clear();
while (top[u] != top[v]) {
if (dpt[top[u]] < dpt[top[v]]) swap(u, v);
query1 (dfn[top[u]], dfn[u], 1);
u = fa[top[u]];
}
if (dpt[u] > dpt[v]) swap(u, v);
query1 (dfn[u], dfn[v], 1);
if (!::v.size()) {
puts("-1");
return;
}
vector <int> vv = ::v;
sort(vv.begin(), vv.end());
reverse(vv.begin(), vv.end());
if (vv.size() < k) {
for (int i : vv) printf("%lld ", i);
puts("");
return;
}
for (int i = 0; i < k; ++ i ) printf("%lld ", vv[i]);
puts("");
return;
}
signed main() {
scanf("%lld", &n);
for (int i = 1, u, v; i < n; ++ i ) {
scanf("%lld%lld", &u, &v);
a[u].push_back(v);
a[v].push_back(u);
}
scanf("%lld", &m);
for (int i = 1; i <= m; ++ i ) scanf("%lld%lld", f + i, p + i);
dfs1 (1, 0);
dfs2 (1, 1);
build (1, n, 1);
for (int i = 1; i <= m; ++ i ) modify (dfn[p[i]], 1, f[i]);
scanf("%lld%lld", &q, &k);
while (q -- ) {
int t, x, y;
scanf("%lld%lld%lld", &t, &x, &y);
if (t == 1) que (x, y);
else if (t == 2) {
update (dfn[p[x]], 1, f[x]);
modify (dfn[y], 1, f[x]);
p[x] = y;
} else {
upd (dfn[p[x]], 1, f[x], y);
f[x] = y;
}
}
return 0;
}