#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 5;
long long n, m, q, sz[N], c[N], head[N], chain[N], pos[N], en[N], cur = 0;
long long par[20][N], dep[N];
vector<long long> G[N], v, w[N];
struct iii {
  long long x, y, z;
  iii(long long x = 0, long long y = 0, long long z = 0) : x(x), y(y), z(z){};
  bool operator<(const iii &dhs) const {
    if (x == dhs.x) return y < dhs.y;
    return x < dhs.x;
  }
};
struct SegmentTree {
  iii t[4 * N];
  long long lazy[4 * N];
  void build_tree(long long l, long long r, long long node) {
    if (l == r) {
      long long val = w[v[l]].back(), indi = w[v[l]].back();
      t[node] = iii(val, v[l], indi);
      return;
    }
    long long mid = (l + r) / 2;
    build_tree(l, mid, node * 2);
    build_tree(mid + 1, r, node * 2 + 1);
    t[node] = min(t[node * 2], t[node * 2 + 1]);
  }
  void updlazy(long long l, long long r, long long node) {
    if (l != r) {
      long long mid = (l + r) / 2;
      if (t[node * 2].x < 1e15) t[node * 2].x += lazy[node];
      if (t[node * 2 + 1].x < 1e15) t[node * 2 + 1].x += lazy[node];
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  iii get(long long l, long long r, long long s, long long e, long long node) {
    updlazy(l, r, node);
    if (l > r || l > e || r < s) return iii(1e15, 1e15, 1e15);
    if (s <= l && r <= e) return t[node];
    long long mid = (l + r) / 2;
    return min(get(l, mid, s, e, node * 2),
               get(mid + 1, r, s, e, node * 2 + 1));
  }
  void updrem(long long l, long long r, long long pos, long long node) {
    updlazy(l, r, node);
    if (l == r) {
      long long cur = w[v[l]].back(), diff = t[node].x - cur;
      w[v[l]].pop_back();
      long long now = w[v[l]].back();
      t[node] = iii(now + diff, v[l], now);
      return;
    }
    long long mid = (l + r) >> 1;
    if (pos <= mid)
      updrem(l, mid, pos, node * 2);
    else
      updrem(mid + 1, r, pos, node * 2 + 1);
    t[node] = min(t[node * 2], t[node * 2 + 1]);
  }
  void upd(long long l, long long r, long long s, long long e, long long node,
           long long val) {
    updlazy(l, r, node);
    if (l > r || l > e || r < s) return;
    if (s <= l && r <= e) {
      if (t[node].x < 1e15) t[node].x += val;
      lazy[node] += val;
      return;
    }
    long long mid = (l + r) / 2;
    upd(l, mid, s, e, node * 2, val);
    upd(mid + 1, r, s, e, node * 2 + 1, val);
    t[node] = min(t[node * 2], t[node * 2 + 1]);
  }
} st;
void predfs(long long u, long long p) {
  sz[u] = 1;
  for (auto v : G[u])
    if (v != p)
      dep[v] = dep[u] + 1, par[0][v] = u, predfs(v, u), sz[u] += sz[v];
}
void hld(long long u, long long p) {
  if (head[cur] == -1) head[cur] = u;
  chain[u] = cur;
  v.push_back(u);
  pos[u] = v.size() - 1;
  long long mx = -1, mxpos = -1;
  for (auto v : G[u])
    if (v != p) {
      if (sz[v] > mx) {
        mx = sz[v];
        mxpos = v;
      }
    }
  if (mxpos != -1) hld(mxpos, u);
  for (auto v : G[u])
    if (v != mxpos && v != p) {
      cur++;
      hld(v, u);
    }
  en[u] = v.size() - 1;
}
long long lca(long long u, long long v) {
  if (dep[u] < dep[v]) swap(u, v);
  long long diff = dep[u] - dep[v];
  for (long long i = 0; i < 20; i++)
    if (diff & (1 << i)) u = par[i][u];
  if (u == v) return u;
  for (long long i = 20 - 1; i >= 0; i--)
    if (par[i][u] != par[i][v]) {
      u = par[i][u];
      v = par[i][v];
    }
  return par[0][u];
}
iii get(long long u, long long v) {
  iii ans = iii(1e15, 1e15, 1e15);
  while (chain[u] != chain[v]) {
    iii temp = st.get(0, n - 1, pos[head[chain[u]]], pos[u], 1);
    ans = min(ans, temp);
    u = par[0][head[chain[u]]];
  }
  iii temp = st.get(0, n - 1, pos[v], pos[u], 1);
  ans = min(ans, temp);
  return ans;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> q;
  for (long long i = 1; i < n; i++) {
    long long u, v;
    cin >> u >> v;
    u--;
    v--;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  memset(chain, -1, sizeof(chain));
  memset(head, -1, sizeof(head));
  memset(par, -1, sizeof(par));
  dep[0] = 0;
  predfs(0, -1);
  hld(0, -1);
  for (long long i = 1; i < 20; i++)
    for (long long j = 0; j < n; j++)
      if (par[i - 1][j] != -1) par[i][j] = par[i - 1][par[i - 1][j]];
  for (long long i = 1; i < m + 1; i++) {
    long long c;
    cin >> c;
    c--;
    w[c].push_back(i);
  }
  for (long long i = 0; i < n; i++) {
    w[i].push_back(1e15);
    sort(w[i].begin(), w[i].end(), greater<long long>());
  }
  st.build_tree(0, n - 1, 1);
  while (q--) {
    long long t;
    cin >> t;
    if (t == 2) {
      long long v, k;
      cin >> v >> k;
      v--;
      long long l = pos[v], r = en[v];
      st.upd(0, n - 1, l, r, 1, k);
    } else {
      long long v, u, k;
      cin >> v >> u >> k;
      v--;
      u--;
      long long tmp = lca(u, v);
      vector<long long> res;
      for (long long i = 0; i < k; i++) {
        iii cur = get(u, tmp);
        cur = min(cur, get(v, tmp));
        if (cur.x == 1e15) break;
        res.push_back(cur.z);
        st.updrem(0, n - 1, pos[cur.y], 1);
      }
      cout << res.size() << " ";
      for (auto i : res) cout << i << " ";
      cout << "\n";
    }
  }
  return 0;
}
