#include <bits/stdc++.h>
using namespace std;
const int mxn = 100005;
const long long inf = 1e15;
int n, m, q, a[mxn];
vector<int> G[mxn];
vector<long long> W[mxn];
pair<long long, long long> seg[mxn * 4];
long long lazy[mxn * 4];
void build(int nd = 1, int l = 1, int r = n) {
  if (l == r) {
    seg[nd] = {W[l].back(), W[l].back()};
    return;
  }
  int mid = l + (r - l) / 2, lft = nd << 1, rgt = lft | 1;
  build(lft, l, mid);
  build(rgt, mid + 1, r);
  seg[nd] = min(seg[lft], seg[rgt]);
}
inline void propagate(int nd, int l, int r) {
  seg[nd].first += lazy[nd];
  if (l != r) {
    lazy[nd << 1] += lazy[nd];
    lazy[(nd << 1) | 1] += lazy[nd];
  }
  lazy[nd] = 0;
}
void update(int L, int R, long long vlu, int nd = 1, int l = 1, int r = n) {
  if (lazy[nd]) propagate(nd, l, r);
  if (L > R or l > R or r < L) return;
  if (l >= L and r <= R) {
    lazy[nd] += vlu;
    propagate(nd, l, r);
    return;
  }
  int mid = l + (r - l) / 2, lft = nd << 1, rgt = lft | 1;
  update(L, R, vlu, lft, l, mid);
  update(L, R, vlu, rgt, mid + 1, r);
  seg[nd] = min(seg[lft], seg[rgt]);
}
void update1(int L, int R, int nd = 1, int l = 1, int r = n) {
  if (lazy[nd]) propagate(nd, l, r);
  if (L > R or l > R or r < L) return;
  if (l >= L and r <= R) {
    long long extra = seg[nd].first - seg[nd].second;
    seg[nd] = {W[l].back(), W[l].back()};
    seg[nd].first += extra;
    return;
  }
  int mid = l + (r - l) / 2, lft = nd << 1, rgt = lft | 1;
  update1(L, R, lft, l, mid);
  update1(L, R, rgt, mid + 1, r);
  seg[nd] = min(seg[lft], seg[rgt]);
}
pair<long long, long long> query(int L, int R, int nd = 1, int l = 1,
                                 int r = n) {
  if (lazy[nd]) propagate(nd, l, r);
  if (L > R or l > R or r < L) return {inf, inf};
  if (l >= L and r <= R) return seg[nd];
  int mid = l + (r - l) / 2, lft = nd << 1, rgt = lft | 1;
  return min(query(L, R, lft, l, mid), query(L, R, rgt, mid + 1, r));
}
int dpth, sz[mxn], prnt[mxn];
int h[mxn], head[mxn], st[mxn], ed[mxn];
void dfs(int u = 1, int p = 0) {
  h[u] = h[p] + 1;
  prnt[u] = p, sz[u] = 1;
  for (auto& v : G[u]) {
    if (v == p) continue;
    dfs(v, u), sz[u] += sz[v];
    if (sz[v] >= sz[G[u][0]]) swap(v, G[u][0]);
  }
}
void decompose(int u = 1, int p = 0) {
  st[u] = ++dpth;
  for (auto& v : G[u]) {
    if (v == p) continue;
    head[v] = (v == G[u][0]) ? head[u] : v;
    decompose(v, u);
  }
  ed[u] = dpth;
}
int lca_of(int u, int v) {
  while (head[u] != head[v]) {
    if (h[head[u]] > h[head[v]])
      u = prnt[head[u]];
    else
      v = prnt[head[v]];
  }
  return h[u] < h[v] ? u : v;
}
pair<long long, long long> min_of_path(int lca, int u) {
  pair<long long, long long> ret = {inf, inf};
  while (head[lca] != head[u]) {
    ret = min(ret, query(st[head[u]], st[u]));
    u = prnt[head[u]];
  }
  return min(ret, query(st[lca], st[u]));
}
void solution(int u, int v, int k) {
  int lca = lca_of(u, v);
  vector<int> res;
  while (k--) {
    pair<long long, long long> mn = min_of_path(lca, u);
    mn = min(mn, min_of_path(lca, v));
    if (mn.first >= inf) break;
    res.push_back(mn.second);
    W[a[mn.second]].pop_back();
    update1(a[mn.second], a[mn.second]);
  }
  printf("%d", res.size());
  for (int i = 0, sz = res.size(); i < sz; i++) {
    printf(" %d", res[i]);
  }
  printf("\n");
}
int main() {
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 1, u, v; i < n; i++) {
    scanf("%d %d", &u, &v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  dfs();
  decompose();
  for (int i = 1, w; i <= m; i++) {
    scanf("%d", &w);
    a[i] = st[w];
    W[st[w]].push_back(i);
  }
  for (int i = 1; i <= n; i++) {
    W[i].push_back(inf);
    sort(W[i].rbegin(), W[i].rend());
  }
  build();
  while (q--) {
    int t, u, v, k;
    scanf("%d %d %d", &t, &u, &v);
    if (t == 1) {
      scanf("%d", &k);
      solution(u, v, k);
    } else {
      update(st[u], ed[u], v);
    }
  }
  return 0;
}
