#include <bits/stdc++.h>
using namespace std;
inline int in() {
  int32_t x;
  scanf("%d", &x);
  return x;
}
inline long long lin() {
  long long x;
  scanf("%lld", &x);
  return x;
}
inline string get() {
  char ch[1000010];
  scanf("%s", ch);
  return ch;
}
const int MAX_LG = 21;
const long long maxn = 1e5 + 100;
const long long base = 29;
const long long mod = 1e9 + 7;
const long long INF = 1e18 + 100;
const long long SQ = 317;
long long n, m, q;
vector<long long> g[maxn];
long long pre[maxn], sz[maxn], heavy[maxn], st[maxn], en[maxn],
    cur = 0, head[maxn], tail[maxn], tree_pos[maxn], tree[maxn], used[maxn],
    h[maxn], fen[maxn];
pair<long long, long long> stree[4 * maxn];
long long lazy[4 * maxn];
set<pair<long long, long long> > girls[maxn];
inline void dfs(long long v, long long pr = -1) {
  sz[v] = 1;
  long long maxi = -1;
  st[v] = cur++;
  for (auto u : g[v]) {
    if (u == pr) continue;
    h[u] = h[v] + 1;
    pre[u] = v;
    dfs(u, v);
    sz[v] += sz[u];
    if (sz[u] > maxi) maxi = sz[u], heavy[v] = u;
  }
  en[v] = cur;
}
inline void decompose() {
  dfs(1);
  cur = 0;
  for (long long i = 1; i <= n; i++) {
    if (pre[i] == -1 || heavy[pre[i]] != i) {
      for (long long u = i; u != -1; u = heavy[u])
        tree[cur] = u, tree_pos[u] = cur++, head[u] = i, tail[i] = tree_pos[u];
      for (long long u = i; u != -1; u = heavy[u]) tail[u] = tail[i];
    }
  }
}
inline void add(long long p, long long val) {
  p += 5;
  for (; p < maxn; p += p & -p) fen[p] += val;
}
inline long long fenget(long long p) {
  p += 5;
  long long ret = 0;
  for (; p > 0; p -= p & -p) ret += fen[p];
  return ret;
}
inline void build(long long p = 0, long long l = 0, long long r = n - 1) {
  if (l == r) {
    long long v = tree[l];
    if (girls[v].size()) {
      stree[p] = *girls[v].begin();
      stree[p].second = v;
      used[v] = stree[p].first;
    } else {
      stree[p] = {INF, -1ll};
    }
    return;
  }
  long long mid = (l + r) >> 1;
  build(2 * p + 1, l, mid);
  build(2 * p + 2, mid + 1, r);
  stree[p] = min(stree[2 * p + 1], stree[2 * p + 2]);
}
inline void shift(long long p) {
  lazy[2 * p + 1] += lazy[p], lazy[2 * p + 2] += lazy[p];
  stree[2 * p + 1].first += lazy[p], stree[2 * p + 2].first += lazy[p];
  lazy[p] = 0;
}
inline void update(long long ql, long long qr, long long value, long long p = 0,
                   long long l = 0, long long r = n - 1) {
  if (l > qr || r < ql) return;
  if (l >= ql && r <= qr) {
    lazy[p] += value;
    stree[p].first += value;
    return;
  }
  long long mid = (l + r) >> 1;
  shift(p);
  update(ql, qr, value, 2 * p + 1, l, mid),
      update(ql, qr, value, 2 * p + 2, mid + 1, r);
  stree[p] = min(stree[2 * p + 1], stree[2 * p + 2]);
}
inline pair<long long, long long> ask(long long ql, long long qr,
                                      long long p = 0, long long l = 0,
                                      long long r = n - 1) {
  if (l > qr || r < ql) return {INF, -1};
  if (l >= ql && r <= qr) return stree[p];
  shift(p);
  long long mid = (l + r) >> 1;
  return min(ask(ql, qr, 2 * p + 1, l, mid),
             ask(ql, qr, 2 * p + 2, mid + 1, r));
}
inline long long pk(long long city) {
  pair<long long, long long> bst = *girls[city].begin();
  long long res = bst.second;
  girls[city].erase(bst);
  long long w = girls[city].empty() ? 2e18 : (*(girls[city].begin())).first;
  update(tree_pos[city], tree_pos[city], w - used[city]);
  used[city] = w;
  return res;
}
inline long long getvalue(long long v) {
  return fenget(st[head[v]]);
  return 0;
}
inline pair<long long, long long> get_path(long long u, long long v) {
  pair<long long, long long> ret = {1e18, -1};
  while (head[v] != head[u]) {
    if (h[head[u]] > h[head[v]]) swap(v, u);
    pair<long long, long long> check = ask(tree_pos[head[v]], tree_pos[v]);
    check.first += getvalue(v);
    ret = min(ret, check);
    v = pre[head[v]];
  }
  if (h[u] > h[v]) swap(v, u);
  pair<long long, long long> check = ask(tree_pos[u], tree_pos[v]);
  check.first += getvalue(u);
  ret = min(ret, check);
  return ret;
}
int32_t main() {
  memset(heavy, -1, sizeof heavy);
  memset(pre, -1, sizeof pre);
  n = in(), m = in(), q = in();
  for (long long i = 0; i < n - 1; i++) {
    long long v = in(), u = in();
    g[v].push_back(u);
    g[u].push_back(v);
  }
  for (long long i = 0; i < m; i++) {
    long long v = in();
    girls[v].insert({i, i});
  }
  decompose();
  build();
  while (q--) {
    long long tp = in();
    if (tp == 1) {
      long long v = in(), u = in(), k = in();
      vector<long long> vc;
      while (k--) {
        pair<long long, long long> g = get_path(v, u);
        if (g.second == -1) break;
        long long a = pk(g.second);
        vc.push_back(a);
      }
      printf("%lld ", (long long)vc.size());
      for (auto v : vc) printf("%lld ", v + 1);
      printf("\n");
    } else {
      long long v = in(), k = in();
      add(st[v] + 1, k);
      add(en[v], -k);
      update(tree_pos[v], tail[v], k);
    }
  }
}
