#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const long long INF = 1e18;
int head[N], ver[N << 1], Next[N << 1], tot;
void Add(int x, int y) {
  ver[++tot] = y;
  Next[tot] = head[x];
  head[x] = tot;
}
int top[N], son[N], fa[N], dep[N], len[N], dfn[N], rnk[N], T, ed[N], at[N];
void dfs(int x) {
  len[x] = 1;
  for (int i = head[x]; i; i = Next[i]) {
    int y = ver[i];
    if (y == fa[x]) continue;
    fa[y] = x;
    dep[y] = dep[x] + 1;
    dfs(y);
    len[x] += len[y];
    if (len[y] > len[son[x]]) son[x] = y;
  }
}
void dfs(int x, int t) {
  dfn[x] = ed[x] = ++T;
  rnk[T] = x;
  top[x] = t;
  if (son[x] == 0) return;
  dfs(son[x], t);
  for (int i = head[x]; i; i = Next[i]) {
    int y = ver[i];
    if (y == fa[x] || y == son[x]) continue;
    dfs(y, y);
  }
  ed[x] = T;
}
vector<int> v[N];
set<pair<long long, int> > s[N];
struct T {
  int l, r;
  pair<long long, int> dat;
  long long add;
} tree[N << 2];
void build(int p, int l, int r) {
  tree[p].l = l;
  tree[p].r = r;
  if (l == r) {
    tree[p].dat = *s[l].begin();
    return;
  }
  int mid = l + r >> 1;
  build(p << 1, l, mid);
  build(p << 1 | 1, mid + 1, r);
  tree[p].dat = min(tree[p << 1].dat, tree[p << 1 | 1].dat);
}
void push(int p, long long k) {
  tree[p].add += k;
  tree[p].dat.first += k;
}
void spread(int p) {
  if (tree[p].add) {
    push(p << 1 | 1, tree[p].add);
    push(p << 1, tree[p].add);
    tree[p].add = 0;
  }
}
void change(int p, int l, int r, long long k) {
  if (l <= tree[p].l && r >= tree[p].r) {
    push(p, k);
    return;
  }
  spread(p);
  int mid = tree[p].l + tree[p].r >> 1;
  if (l <= mid) change(p << 1, l, r, k);
  if (r > mid) change(p << 1 | 1, l, r, k);
  tree[p].dat = min(tree[p << 1].dat, tree[p << 1 | 1].dat);
}
void change(int p, int x) {
  if (tree[p].l == tree[p].r) {
    s[x].erase(s[x].begin());
    tree[p].dat = *s[x].begin();
    tree[p].dat.first += tree[p].add;
    return;
  }
  spread(p);
  int mid = tree[p].l + tree[p].r >> 1;
  if (x <= mid)
    change(p << 1, x);
  else
    change(p << 1 | 1, x);
  tree[p].dat = min(tree[p << 1].dat, tree[p << 1 | 1].dat);
}
pair<long long, int> ask(int p, int l, int r) {
  if (l <= tree[p].l && r >= tree[p].r) return tree[p].dat;
  spread(p);
  pair<long long, int> ans = {INF, 0};
  int mid = tree[p].l + tree[p].r >> 1;
  if (r <= mid) return ask(p << 1, l, r);
  if (l > mid) return ask(p << 1 | 1, l, r);
  return min(ask(p << 1, l, r), ask(p << 1 | 1, l, r));
}
int split(int x, int y) {
  pair<long long, int> ans = {INF, 0};
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y);
    ans = min(ans, ask(1, dfn[top[x]], dfn[x]));
    x = fa[top[x]];
  }
  if (dep[x] > dep[y]) swap(x, y);
  ans = min(ans, ask(1, dfn[x], dfn[y]));
  return ans.second;
}
int main() {
  int n, m, q;
  cin >> n >> m >> q;
  for (int i = 1; i < n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    Add(x, y);
    Add(y, x);
  }
  dfs(1);
  dfs(1, 1);
  for (int i = 1; i <= n; i++) s[i].insert({INF, 0});
  for (int i = 1; i <= m; i++) {
    int x;
    scanf("%d", &x);
    at[i] = x;
    s[dfn[x]].insert({i, i});
  }
  at[0] = N - 1;
  build(1, 1, n);
  for (int i = 1; i <= q; i++) {
    int opt, l, r, k;
    scanf("%d%d%d", &opt, &l, &r);
    if (opt == 2) {
      change(1, dfn[l], ed[l], r);
    } else {
      scanf("%d", &k);
      vector<int> ans;
      for (int j = 0; j < k; j++) {
        int t = split(l, r);
        if (t == 0) break;
        ans.push_back(t);
        change(1, dfn[at[t]]);
      }
      printf("%d", ans.size());
      for (int j = 0; j < ans.size(); j++) printf(" %d", ans[j]);
      puts("");
    }
  }
}
