package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
const INF int64 = 100000000000000000
type Node struct {
minW int64
id int
lazy int64
}
var (
n, m, q int
adj [][]int
girls [][]int
head []int
depth, parent, sz, top, tin, tout, rev_tin []int
timer int
tree []Node
)
var scanner *bufio.Scanner
func init() {
scanner = bufio.NewScanner(os.Stdin)
scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024)
scanner.Split(bufio.ScanWords)
}
func readInt() int {
scanner.Scan()
v, _ := strconv.Atoi(scanner.Text())
return v
}
func dfs1(u, p, d int) {
depth[u] = d
parent[u] = p
sz[u] = 1
for _, v := range adj[u] {
if v != p {
dfs1(v, u, d+1)
sz[u] += sz[v]
}
}
}
func dfs2(u, p, top_node int) {
top[u] = top_node
tin[u] = timer
rev_tin[timer] = u
timer++
heavy_child := -1
heavy_sz := -1
for _, v := range adj[u] {
if v != p && sz[v] > heavy_sz {
heavy_sz = sz[v]
heavy_child = v
}
}
if heavy_child != -1 {
dfs2(heavy_child, u, top_node)
}
for _, v := range adj[u] {
if v != p && v != heavy_child {
dfs2(v, u, v)
}
}
tout[u] = timer - 1
}
func pushUp(node int) {
lc, rc := node*2, node*2+1
if tree[lc].minW < tree[rc].minW {
tree[node].minW = tree[lc].minW
tree[node].id = tree[lc].id
} else if tree[lc].minW > tree[rc].minW {
tree[node].minW = tree[rc].minW
tree[node].id = tree[rc].id
} else {
if tree[lc].id < tree[rc].id {
tree[node].id = tree[lc].id
} else {
tree[node].id = tree[rc].id
}
tree[node].minW = tree[lc].minW
}
}
func pushDown(node int) {
if tree[node].lazy != 0 {
lz := tree[node].lazy
tree[node*2].minW += lz
tree[node*2].lazy += lz
tree[node*2+1].minW += lz
tree[node*2+1].lazy += lz
tree[node].lazy = 0
}
}
func build(node, l, r int) {
if l == r {
u := rev_tin[l]
if len(girls[u]) > 0 {
tree[node] = Node{minW: int64(girls[u][0]), id: u, lazy: 0}
} else {
tree[node] = Node{minW: INF, id: u, lazy: 0}
}
return
}
mid := (l + r) / 2
build(node*2, l, mid)
build(node*2+1, mid+1, r)
pushUp(node)
}
func update_point(node, l, r, idx int, diff int64) {
if l == r {
tree[node].minW += diff
return
}
pushDown(node)
mid := (l + r) / 2
if idx <= mid {
update_point(node*2, l, mid, idx, diff)
} else {
update_point(node*2+1, mid+1, r, idx, diff)
}
pushUp(node)
}
func update_range(node, l, r, ql, qr int, val int64) {
if ql <= l && r <= qr {
tree[node].minW += val
tree[node].lazy += val
return
}
pushDown(node)
mid := (l + r) / 2
if ql <= mid {
update_range(node*2, l, mid, ql, qr, val)
}
if qr > mid {
update_range(node*2+1, mid+1, r, ql, qr, val)
}
pushUp(node)
}
func query(node, l, r, ql, qr int) (int64, int) {
if ql <= l && r <= qr {
return tree[node].minW, tree[node].id
}
pushDown(node)
mid := (l + r) / 2
resW, resId := int64(INF), int(1e9)
if ql <= mid {
w, id := query(node*2, l, mid, ql, qr)
if w < resW || (w == resW && id < resId) {
resW, resId = w, id
}
}
if qr > mid {
w, id := query(node*2+1, mid+1, r, ql, qr)
if w < resW || (w == resW && id < resId) {
resW, resId = w, id
}
}
return resW, resId
}
func query_path(u, v int) (int64, int) {
resW := int64(INF)
resId := int(1e9)
for top[u] != top[v] {
if depth[top[u]] < depth[top[v]] {
u, v = v, u
}
w, id := query(1, 0, n-1, tin[top[u]], tin[u])
if w < resW || (w == resW && id < resId) {
resW, resId = w, id
}
u = parent[top[u]]
}
if depth[u] > depth[v] {
u, v = v, u
}
w, id := query(1, 0, n-1, tin[u], tin[v])
if w < resW || (w == resW && id < resId) {
resW, resId = w, id
}
return resW, resId
}
func main() {
n = readInt()
m = readInt()
q = readInt()
adj = make([][]int, n+1)
for i := 0; i < n-1; i++ {
u, v := readInt(), readInt()
adj[u] = append(adj[u], v)
adj[v] = append(adj[v], u)
}
girls = make([][]int, n+1)
for i := 1; i <= m; i++ {
c := readInt()
girls[c] = append(girls[c], i)
}
head = make([]int, n+1)
depth = make([]int, n+1)
parent = make([]int, n+1)
sz = make([]int, n+1)
top = make([]int, n+1)
tin = make([]int, n+1)
tout = make([]int, n+1)
rev_tin = make([]int, n+1)
if n > 0 {
dfs1(1, 0, 0)
dfs2(1, 0, 1)
tree = make([]Node, 4*n+1)
build(1, 0, n-1)
}
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
ans := make([]int, 0, n)
for i := 0; i < q; i++ {
t := readInt()
if t == 1 {
v := readInt()
u := readInt()
k := readInt()
ans = ans[:0]
for j := 0; j < k; j++ {
if n == 0 {
break
}
minW, minId := query_path(v, u)
if minW >= INF/2 {
break
}
gId := girls[minId][head[minId]]
ans = append(ans, gId)
head[minId]++
var diff int64
if head[minId] < len(girls[minId]) {
diff = int64(girls[minId][head[minId]] - girls[minId][head[minId]-1])
} else {
diff = INF
}
update_point(1, 0, n-1, tin[minId], diff)
}
fmt.Fprintf(out, "%d", len(ans))
for _, g := range ans {
fmt.Fprintf(out, " %d", g)
}
fmt.Fprintln(out)
} else {
v := readInt()
k := readInt()
if n > 0 {
update_range(1, 0, n-1, tin[v], tout[v], int64(k))
}
}
}
}