#include <bits/stdc++.h>
using namespace std;
const long long inf = (1LL << 45);
const int N = 100123;
int z, n, m, q, t, a, b, c, u, v, k;
int CHS, ID, T;
int par[N];
int subtree[N];
int chain[N];
int id[N];
int rid[N];
int head_chain[N];
int depth[N];
vector<int> nbs[N];
int anc[20][N];
int logn;
vector<int> g[N];
int pre[N];
int post[N];
pair<pair<long long, long long>, long long> tree[N << 2];
long long lazy[N << 2];
void update(int v, int l, int r) {
  if (l >= r) {
    if (g[rid[l]].size()) {
      tree[v].first.second = g[rid[l]].back();
    }
    return;
  }
  pair<long long, long long> a = {tree[2 * v].first.first + lazy[2 * v],
                                  tree[2 * v].first.second};
  pair<long long, long long> b = {tree[2 * v + 1].first.first + lazy[2 * v + 1],
                                  tree[2 * v + 1].first.second};
  if (a <= b) {
    tree[v] = {a, tree[2 * v].second};
  } else {
    tree[v] = {b, tree[2 * v + 1].second};
  }
}
void build(int v, int l, int r) {
  if (l >= r) {
    if (g[rid[l]].size()) {
      tree[v] = {{g[rid[l]].back(), g[rid[l]].back()}, l};
    } else {
      tree[v] = {{inf, inf}, l};
    }
    return;
  }
  int mid = (l + r) >> 1;
  build(2 * v, l, mid);
  build(2 * v + 1, mid + 1, r);
  update(v, l, r);
}
void push(int v, int l, int r) {
  if (l >= r) {
    tree[v].first.first += lazy[v];
    lazy[v] = 0;
    return;
  }
  lazy[2 * v] += lazy[v];
  lazy[2 * v + 1] += lazy[v];
  lazy[v] = 0;
  update(v, l, r);
}
void insert(int v, int l, int r, int ql, int qr, long long value) {
  push(v, l, r);
  if (ql <= l && r <= qr) {
    lazy[v] += value;
    update(v, l, r);
    return;
  }
  int mid = (l + r) >> 1;
  if (mid >= ql) insert(2 * v, l, mid, ql, qr, value);
  if (mid + 1 <= qr) insert(2 * v + 1, mid + 1, r, ql, qr, value);
  update(v, l, r);
}
pair<pair<long long, long long>, long long> query(int v, int l, int r, int ql,
                                                  int qr) {
  push(v, l, r);
  if (ql <= l && r <= qr) {
    update(v, l, r);
    return tree[v];
  }
  int mid = (l + r) >> 1;
  pair<pair<long long, long long>, long long> res = {{inf, inf}, -1};
  if (mid >= ql) res = min(res, query(2 * v, l, mid, ql, qr));
  if (mid + 1 <= qr) res = min(res, query(2 * v + 1, mid + 1, r, ql, qr));
  update(v, l, r);
  return res;
}
void hld(int v, int p) {
  if (head_chain[CHS] < 0) head_chain[CHS] = v;
  chain[v] = CHS;
  id[v] = ++ID;
  rid[ID] = v;
  int sc = -1, scv = -1;
  for (int i = 0; i < (int)(int)nbs[v].size(); i++)
    if (nbs[v][i] != p) {
      if (scv < subtree[nbs[v][i]]) sc = i, scv = subtree[nbs[v][i]];
    }
  if (sc < 0) return;
  hld(nbs[v][sc], v);
  for (int i = 0; i < (int)(int)nbs[v].size(); i++)
    if (nbs[v][i] != p && i != sc) {
      CHS++;
      hld(nbs[v][i], v);
    }
}
int dfs1(int v, int p, int d) {
  depth[v] = d;
  par[v] = p;
  for (int i = 0; i < (int)nbs[v].size(); i++)
    if (nbs[v][i] != p) {
      subtree[v] += dfs1(nbs[v][i], v, d + 1);
    }
  return ++subtree[v];
}
void dfs2(int v, int p) {
  pre[v] = ++T;
  assert(pre[v] == id[v]);
  for (int w : nbs[v])
    if (w != p) {
      dfs2(w, v);
    }
  post[v] = T;
}
void lca() {
  for (int j = 0; j <= logn; j++)
    for (int i = 1; i <= n; i++) {
      anc[j][i] = (j ? anc[j - 1][anc[j - 1][i]] : par[i]);
    }
}
int lca_query(int a, int b) {
  if (depth[a] < depth[b]) swap(a, b);
  for (int p = logn; p >= 0; p--)
    if (depth[a] - (1 << p) >= depth[b]) a = anc[p][a];
  for (int p = logn; p >= 0; p--)
    if (anc[p][a] != anc[p][b]) {
      a = anc[p][a];
      b = anc[p][b];
    }
  return (a == b ? a : anc[0][a]);
}
struct chn {
  int a, b;
  pair<pair<long long, long long>, long long> res;
  chn(int _a, int _b) : a(_a), b(_b) { recompute(); }
  void recompute() { res = query(1, 1, n, a, b); }
  bool operator<(const chn& ch) const { return res > ch.res; }
};
priority_queue<chn> chains;
void query_up(int a, int b, int dest, bool last) {
  while (chain[a] != chain[b]) {
    int hc = head_chain[chain[a]];
    chains.push({id[hc], id[a]});
    a = par[hc];
  }
  if (last)
    chains.push({id[b], id[a]});
  else if (b != a)
    chains.push({id[b] + 1, id[a]});
}
void query(int a, int b) {
  if (a > b) swap(a, b);
  int l = lca_query(a, b);
  query_up(a, l, l, 1);
  query_up(b, l, l, 0);
}
vector<int> ans;
void ride(int u, int v, int k) {
  ans.clear();
  query(u, v);
  while (chains.size() && k) {
    chn cur = chains.top();
    chains.pop();
    pair<pair<long long, long long>, long long> cur_value = cur.res;
    if (cur_value.first.first >= inf) continue;
    k--;
    int vertex = cur_value.second;
    assert(g[rid[vertex]].size());
    ans.push_back(g[rid[vertex]].back());
    assert(g[rid[vertex]].back() == cur_value.first.second);
    g[rid[vertex]].pop_back();
    int old = ans.back();
    if (!g[rid[vertex]].size()) {
      insert(1, 1, n, vertex, vertex, inf);
    } else {
      int ne = g[rid[vertex]].back();
      assert(ne - old > 0);
      insert(1, 1, n, vertex, vertex, ne - old);
    }
    cur.recompute();
    chains.push(cur);
  }
  while (chains.size()) chains.pop();
}
void add(int v, int k) { insert(1, 1, n, pre[v], post[v], k); }
bool cmp_size(int a, int b) { return subtree[a] < subtree[b]; }
int main() {
  ios_base::sync_with_stdio(0);
  cin >> n >> m >> q;
  memset(depth, -1, sizeof(depth));
  memset(head_chain, -1, sizeof head_chain);
  logn = 17;
  for (int i = 0; i < (int)n - 1; i++) {
    cin >> a >> b;
    nbs[a].push_back(b);
    nbs[b].push_back(a);
  }
  dfs1(1, 0, 0);
  for (int i = 1; i <= n; i++) {
    sort(nbs[i].begin(), nbs[i].end(), cmp_size);
    reverse(nbs[i].begin(), nbs[i].end());
  }
  lca();
  hld(1, 0);
  dfs2(1, 0);
  for (int i = 1; i <= m; i++) {
    cin >> a;
    g[a].push_back(i);
  }
  for (int i = 1; i <= n; i++) {
    sort(g[i].begin(), g[i].end());
    reverse(g[i].begin(), g[i].end());
  }
  build(1, 1, n);
  while (q--) {
    cin >> t;
    if (t == 1) {
      cin >> u >> v >> k;
      ride(u, v, k);
      cout << ans.size() << " ";
      for (int second : ans) cout << second << " ";
      cout << endl;
    } else {
      cin >> v >> k;
      add(v, k);
    }
  }
}
