#include <bits/stdc++.h>
using namespace std;
const int N = 1 << 17;
const int LOG = 17;
int n, m, q, tick;
int id[N], st[N], nd[N], ch[N], dep[N], lca[LOG][N];
vector<int> v[N];
void dfs(int p, int x) {
  dep[x] = dep[p] + 1;
  lca[0][x] = p;
  for (int i = 1; i < LOG; i++) lca[i][x] = lca[i - 1][lca[i - 1][x]];
  ch[x] = 1;
  for (auto u : v[x]) {
    if (u != p) {
      dfs(x, u);
      ch[x] += ch[u];
    }
  }
}
int head[N], ww[N];
void dfs2(int p, int x, int h) {
  id[x] = ++tick;
  st[x] = tick;
  ww[tick] = x;
  head[x] = h;
  int mx = -1;
  for (auto u : v[x]) {
    if (u != p) {
      if (mx == -1 or ch[u] > ch[mx]) mx = u;
    }
  }
  if (mx != -1) dfs2(x, mx, h);
  for (auto u : v[x]) {
    if (u != p and u != mx) dfs2(x, u, u);
  }
  nd[x] = tick;
}
int getLca(int x, int y) {
  if (!x) return y;
  if (!y) return x;
  if (dep[x] < dep[y]) swap(x, y);
  for (int i = LOG - 1; i >= 0; i--)
    if (dep[x] - (1 << i) >= dep[y]) x = lca[i][x];
  if (x == y) return x;
  for (int i = LOG - 1; i >= 0; i--)
    if (lca[i][x] != lca[i][y]) x = lca[i][x], y = lca[i][y];
  return lca[0][x];
}
vector<int> jun[N];
namespace tree {
pair<long long, int> t[N << 1];
long long lazy[N << 1];
void Do(int x, long long v) {
  t[x].first += v;
  lazy[x] += v;
}
void push(int x) {
  Do(x + x, lazy[x]);
  Do(x + x + 1, lazy[x]);
  lazy[x] = 0;
}
void up(int x, int l, int r, int x1, int x2, long long v) {
  if (x2 < l or r < x1) return;
  if (x1 <= l and r <= x2) {
    Do(x, v);
    return;
  }
  push(x);
  int m = (l + r) >> 1;
  up(x + x, l, m, x1, x2, v);
  up(x + x + 1, m + 1, r, x1, x2, v);
  t[x] = min(t[x + x], t[x + x + 1]);
}
void update(int x, int l, int r, int x1) {
  if (l == r) {
    if (jun[ww[l]].size())
      t[x] = {jun[ww[l]].back() + lazy[x], ww[l]};
    else
      t[x] = {1e18, -1};
    return;
  }
  push(x);
  int m = (l + r) >> 1;
  if (x1 <= m)
    update(x + x, l, m, x1);
  else
    update(x + x + 1, m + 1, r, x1);
  t[x] = min(t[x + x], t[x + x + 1]);
}
void init(int x, int l, int r) {
  if (l == r) {
    if (jun[ww[l]].size())
      t[x] = {jun[ww[l]].back(), ww[l]};
    else
      t[x] = {1e18, -1};
  } else {
    int m = (l + r) >> 1;
    init(x + x, l, m);
    init(x + x + 1, m + 1, r);
    t[x] = min(t[x + x], t[x + x + 1]);
  }
}
pair<long long, int> get(int x, int l, int r, int x1, int x2) {
  if (x2 < l or r < x1) return {1e18, -1};
  if (x1 <= l and r <= x2) return t[x];
  push(x);
  int m = (l + r) >> 1;
  return min(get(x + x, l, m, x1, x2), get(x + x + 1, m + 1, r, x1, x2));
}
}  // namespace tree
pair<long long, int> get(int x, int y) {
  pair<long long, int> res = {1e18, -1};
  while (dep[x] >= dep[y]) {
    int a = head[x];
    if (dep[a] < dep[y]) a = y;
    res = min(res, tree ::get(1, 1, n, id[a], id[x]));
    x = lca[0][a];
  }
  return res;
}
int w[N];
int main() {
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 1; i < n; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    v[x].push_back(y);
    v[y].push_back(x);
  }
  for (int i = 1; i <= m; i++) {
    scanf("%d", w + i);
    jun[w[i]].push_back(i);
  }
  for (int i = 1; i <= n; i++) {
    reverse(jun[i].begin(), jun[i].end());
  }
  dfs(0, 1);
  tick = 0;
  dfs2(0, 1, 1);
  tree ::init(1, 1, n);
  for (int i = 1; i <= q; i++) {
    int c;
    scanf("%d", &c);
    if (c == 1) {
      int x, y, k;
      scanf("%d %d %d", &x, &y, &k);
      int lca = getLca(x, y);
      vector<int> v;
      for (int it = 0; it < k; it++) {
        auto tmp = min(get(x, lca), get(y, lca));
        if (tmp.first > 5e17) break;
        v.push_back(jun[tmp.second].back());
        jun[tmp.second].pop_back();
        tree ::update(1, 1, n, st[tmp.second]);
      }
      printf("%d", v.size());
      for (auto x : v) printf(" %d", x);
      puts("");
    } else {
      int x, k;
      scanf("%d %d", &x, &k);
      tree ::up(1, 1, n, st[x], nd[x], k);
    }
  }
  return 0;
}
