#include <bits/stdc++.h>
using namespace std;
const long long INF = 1LL << 62;
long long powmod(long long a, long long b) {
  long long res = 1;
  a %= 1000000007;
  for (; b; b >>= 1) {
    if (b & 1) res = res * a % 1000000007;
    a = a * a % 1000000007;
  }
  return res;
}
template <typename T>
inline bool chkmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T>
inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
int n, m;
int fa[301000];
long long laz[301000 << 2];
int ff[301000];
pair<long long, int> mi[301000 << 2];
int now[301000];
int dep[301000], ed[301000], top[301000], dfn[301000], siz[301000], lab[301000],
    son[301000], fc[301000];
int tot;
vector<int> tree[301000];
vector<pair<long long, int> > s[301000];
void dfs(int u) {
  siz[u] = 1;
  for (auto v : tree[u]) {
    if (v == fa[u]) continue;
    dep[v] = dep[u] + 1;
    fa[v] = u;
    dfs(v);
    siz[u] += siz[v];
    if (siz[v] > siz[son[u]]) son[u] = v;
  }
}
void dfs1(int u, int tp) {
  top[u] = tp, dfn[u] = ++tot, lab[tot] = u;
  if (son[u]) dfs1(son[u], tp);
  for (auto v : tree[u]) {
    if (v == fa[u] || v == son[u]) continue;
    dfs1(v, v);
  }
  ed[u] = tot;
}
void build(int rt, int ll, int rr) {
  laz[rt] = 0;
  mi[rt] = {INF, 0x3f3f3f3f};
  if (ll == rr) {
    if (now[lab[ll]] < s[lab[ll]].size()) {
      mi[rt] = s[lab[ll]][0];
      ff[lab[ll]] = s[lab[ll]][0].first;
      now[lab[ll]]++;
    }
    return;
  }
  build((rt << 1), ll, ((ll + rr) / 2));
  build(((rt << 1) | 1), ((ll + rr) / 2) + 1, rr);
  mi[rt] = min(mi[(rt << 1)], mi[((rt << 1) | 1)]);
}
void push_down(int rt) {
  if (laz[rt]) {
    if (mi[(rt << 1)].first != INF) {
      laz[(rt << 1)] += laz[rt];
      mi[(rt << 1)] = {mi[(rt << 1)].first + laz[rt], mi[(rt << 1)].second};
    }
    if (mi[((rt << 1) | 1)].first != INF) {
      laz[((rt << 1) | 1)] += laz[rt];
      mi[((rt << 1) | 1)] = {mi[((rt << 1) | 1)].first + laz[rt],
                             mi[((rt << 1) | 1)].second};
    }
    laz[rt] = 0;
  }
}
pair<long long, int> query_mi(int rt, int ll, int rr, int l, int r) {
  if (ll == l && rr == r) return mi[rt];
  push_down(rt);
  pair<long long, int> res;
  if (r <= ((ll + rr) / 2))
    res = query_mi((rt << 1), ll, ((ll + rr) / 2), l, r);
  else if (l > ((ll + rr) / 2))
    res = query_mi(((rt << 1) | 1), ((ll + rr) / 2) + 1, rr, l, r);
  else
    res = min(query_mi((rt << 1), ll, ((ll + rr) / 2), l, ((ll + rr) / 2)),
              query_mi(((rt << 1) | 1), ((ll + rr) / 2) + 1, rr,
                       ((ll + rr) / 2) + 1, r));
  mi[rt] = min(mi[(rt << 1)], mi[((rt << 1) | 1)]);
  return res;
}
void update(int rt, int ll, int rr, int x, pair<long long, int> v) {
  if (ll == rr) {
    mi[rt] = v.first == INF ? make_pair(INF, 0x3f3f3f3f)
                            : make_pair(v.first + laz[rt], v.second);
    return;
  }
  push_down(rt);
  if (x <= ((ll + rr) / 2))
    update((rt << 1), ll, ((ll + rr) / 2), x, v);
  else
    update(((rt << 1) | 1), ((ll + rr) / 2) + 1, rr, x, v);
  mi[rt] = min(mi[(rt << 1)], mi[((rt << 1) | 1)]);
}
void update(int rt, int ll, int rr, int l, int r, int v) {
  if (ll == l && rr == r) {
    laz[rt] += v;
    mi[rt].first += v;
    return;
  }
  push_down(rt);
  if (r <= ((ll + rr) / 2))
    update((rt << 1), ll, ((ll + rr) / 2), l, r, v);
  else if (l > ((ll + rr) / 2))
    update(((rt << 1) | 1), ((ll + rr) / 2) + 1, rr, l, r, v);
  else
    update((rt << 1), ll, ((ll + rr) / 2), l, ((ll + rr) / 2), v),
        update(((rt << 1) | 1), ((ll + rr) / 2) + 1, rr, ((ll + rr) / 2) + 1, r,
               v);
  mi[rt] = min(mi[(rt << 1)], mi[((rt << 1) | 1)]);
}
int ans[301000];
pair<long long, int> query(int u, int v) {
  pair<long long, int> res = {INF, 0x3f3f3f3f};
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    chkmin(res, query_mi(1, 1, n, dfn[top[u]], dfn[u]));
    u = fa[top[u]];
  }
  if (dep[u] > dep[v]) swap(u, v);
  chkmin(res, query_mi(1, 1, n, dfn[u], dfn[v]));
  return res;
}
void fckn(int u, int v, int c) {
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    update(1, 1, n, dfn[top[u]], dfn[u], c);
    u = fa[top[u]];
  }
  if (u == v) return;
  if (dep[u] > dep[v]) swap(u, v);
  update(1, 1, n, dfn[u], dfn[v], c);
}
int main() {
  n = read(), m = read();
  int q = read();
  for (int i = 1; i < n; i++) {
    int u = read(), v = read();
    tree[u].push_back(v), tree[v].push_back(u);
  }
  for (int i = 1; i <= m; i++) {
    int x = read();
    s[x].push_back({i, x});
  }
  for (int i = 1; i <= n; i++)
    if (s[i].size() > 0) sort(s[i].begin(), s[i].end());
  dfs(1);
  dfs1(1, 1);
  build(1, 1, n);
  for (int i = 0; i < q; i++) {
    int t = read(), u = read(), v = read();
    if (t == 1) {
      int k = read();
      int tmp = 0;
      for (int j = 0; j < k; j++) {
        pair<long long, int> x = query(u, v);
        if (x.first == INF) break;
        ans[tmp++] = ff[x.second];
        if (s[x.second].size() > now[x.second])
          update(1, 1, n, dfn[x.second], s[x.second][now[x.second]]),
              ff[x.second] = s[x.second][now[x.second]].first, now[x.second]++;
        else
          update(1, 1, n, dfn[x.second], make_pair(INF, 0x3f3f3f3f));
      }
      printf("%d ", tmp);
      for (int i = 0; i < tmp; i++) printf("%d ", ans[i]);
      puts("");
    } else {
      update(1, 1, n, dfn[u], ed[u], v);
    }
  }
  return 0;
}
