#include <bits/stdc++.h>
#pragma GCC optimize("O2")
#pragma GCC optimize("unroll-loops")
using namespace std;
const long double eps = 1e-7;
const int inf = 1000000010;
const long long INF = 10000000000000010LL;
const int mod = 1000000007;
const int MAXN = 100010, LOG = 20;
int n, m, k, q, u, v, x, y, t, a, b, ans;
int stt[MAXN], fnt[MAXN], ras[MAXN], timer = 1;
int sz[MAXN], par[MAXN], head[MAXN], h[MAXN];
long long fen[MAXN];
pair<long long, int> seg[MAXN << 2];
long long lazy[MAXN << 2];
set<int> st[MAXN];
vector<int> G[MAXN];
void add(int pos, long long val) {
  for (; pos < MAXN; pos += pos & -pos) fen[pos] += val;
}
long long get(int pos) {
  long long res = 0;
  for (; pos; pos -= pos & -pos) res += fen[pos];
  return res;
}
int dfs1(int node) {
  h[node] = h[par[node]] + 1;
  for (int v : G[node])
    if (v != par[node]) {
      par[v] = node;
      sz[node] += dfs1(v);
    }
  return ++sz[node];
}
void dfs2(int node, int hd) {
  head[node] = hd;
  stt[node] = timer++;
  ras[stt[node]] = node;
  int big = 0;
  for (int v : G[node])
    if (v != par[node] && sz[v] > sz[big]) big = v;
  if (big) dfs2(big, hd);
  for (int v : G[node])
    if (v != par[node] && v != big) dfs2(v, v);
  fnt[node] = timer;
}
pair<long long, int> Build(int id, int tl, int tr) {
  if (tr - tl == 1) return seg[id] = {INF, ras[tl]};
  int mid = (tl + tr) >> 1;
  return seg[id] = min(Build(id << 1, tl, mid), Build(id << 1 | 1, mid, tr));
}
void add_lazy(int id, long long val) {
  seg[id].first += val;
  lazy[id] += val;
}
void shift(int id) {
  if (!lazy[id]) return;
  add_lazy(id << 1, lazy[id]);
  add_lazy(id << 1 | 1, lazy[id]);
  lazy[id] = 0;
}
void Add(int id, int tl, int tr, int l, int r, long long val) {
  if (r <= tl || tr <= l) return;
  if (l <= tl && tr <= r) {
    add_lazy(id, val);
    return;
  }
  shift(id);
  int mid = (tl + tr) >> 1;
  Add(id << 1, tl, mid, l, r, val);
  Add(id << 1 | 1, mid, tr, l, r, val);
  seg[id] = min(seg[id << 1], seg[id << 1 | 1]);
}
pair<long long, int> Get(int id, int tl, int tr, int l, int r) {
  if (r <= tl || tr <= l) return seg[0];
  if (l <= tl && tr <= r) return seg[id];
  shift(id);
  int mid = (tl + tr) >> 1;
  return min(Get(id << 1, tl, mid, l, r), Get(id << 1 | 1, mid, tr, l, r));
}
void Set(int id, int tl, int tr, int pos, long long val) {
  if (pos < tl || tr <= pos) return;
  if (tr - tl == 1) {
    seg[id].first = val;
    return;
  }
  shift(id);
  int mid = (tl + tr) >> 1;
  Set(id << 1, tl, mid, pos, val);
  Set(id << 1 | 1, mid, tr, pos, val);
  seg[id] = min(seg[id << 1], seg[id << 1 | 1]);
}
pair<long long, int> GetPath(int u, int v) {
  pair<long long, int> res = {INF, -1};
  while (head[u] != head[v]) {
    if (h[head[u]] > h[head[v]]) swap(u, v);
    res = min(res, Get(1, 1, n + 1, stt[head[v]], stt[v] + 1));
    v = par[head[v]];
  }
  if (h[u] > h[v]) swap(u, v);
  res = min(res, Get(1, 1, n + 1, stt[u], stt[v] + 1));
  return res;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> q;
  for (int i = 1; i < n; i++) {
    cin >> u >> v;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  for (int i = 1; i <= m; i++) cin >> x, st[x].insert(i);
  dfs1(1);
  dfs2(1, 1);
  Build(1, 1, n + 1);
  seg[0] = {INF, 0};
  for (int i = 1; i <= n; i++)
    if (st[i].size()) Set(1, 1, n + 1, stt[i], *st[i].begin());
  while (q--) {
    cin >> t;
    if (t == 2) {
      cin >> v >> x;
      Add(1, 1, n + 1, stt[v], fnt[v], x);
      add(stt[v], +x);
      add(fnt[v], -x);
      continue;
    }
    vector<int> out;
    cin >> u >> v >> k;
    while (k--) {
      pair<long long, int> p = GetPath(u, v);
      if (p.first >= INF) break;
      int v = p.second, id = *st[v].begin();
      out.push_back(id);
      st[v].erase(id);
      if (st[v].empty())
        Set(1, 1, n + 1, stt[v], INF);
      else
        Set(1, 1, n + 1, stt[v], *st[v].begin() + get(stt[v]));
    }
    cout << out.size() << ' ';
    for (int i : out) cout << i << " ";
    cout << '\n';
  }
  return 0;
}
