#include <bits/stdc++.h>
using namespace std;
int L[200000], maxi[200000], par[200000][20], sz[200000], chainhead[200000],
    chainno[200000], pos[200000], rev[200000], curchain, cnt;
int st[200000], en[200000];
int cv[200000];
long long tottree[500000], lazy[500000];
pair<pair<long long, int>, int> tree[500000];
vector<pair<pair<long long, int>, int> > my[200000];
vector<int> vc[200000];
int Lca_query(int p, int q) {
  if (p == q) return p;
  if (L[p] < L[q]) swap(p, q);
  int log = 1;
  while (1) {
    int nexto = log + 1;
    if (L[p] < (1 << nexto)) break;
    log++;
  }
  for (int i = log; i >= 0; i--) {
    if ((L[p] - (1 << i)) >= L[q]) p = par[p][i];
  }
  if (p == q) return p;
  for (int i = log; i >= 0; i--) {
    if (par[p][i] != -1 && par[p][i] != par[q][i]) {
      p = par[p][i];
      q = par[q][i];
    }
  }
  return par[p][0];
}
void build(int n) {
  for (int j = 1; (1 << j) < n; j++) {
    for (int i = 1; i <= n; i++) {
      if (par[i][j - 1] == -1) continue;
      par[i][j] = par[par[i][j - 1]][j - 1];
    }
  }
}
void dfs(int v, int pa, int lev) {
  L[v] = lev;
  par[v][0] = pa;
  sz[v] = 1;
  maxi[v] = -1;
  int ma = 0;
  for (int i = 0; i < vc[v].size(); i++) {
    int w = vc[v][i];
    if (w == pa) continue;
    dfs(w, v, lev + 1);
    sz[v] += sz[w];
    if (sz[w] > ma) {
      ma = sz[w];
      maxi[v] = w;
    }
  }
}
void hld(int v, int par) {
  if (chainhead[curchain] == 0) chainhead[curchain] = v;
  chainno[v] = curchain;
  pos[v] = ++cnt;
  st[v] = cnt;
  rev[cnt] = v;
  if (maxi[v] != -1) hld(maxi[v], v);
  for (int i = 0; i < vc[v].size(); i++) {
    int w = vc[v][i];
    if (w == par || maxi[v] == w) continue;
    curchain++;
    hld(w, v);
  }
  en[v] = cnt;
}
long long big = 100000000000000LL;
pair<pair<long long, int>, int> bigdata =
    make_pair(make_pair(big, 500000), 500000);
pair<pair<long long, int>, int> query(int node, int st, int en, int l, int r) {
  if (st > r or en < l) return bigdata;
  if (lazy[node] != 0) {
    if (tree[node].second != 500000) tree[node].first.first += lazy[node];
    tottree[node] += lazy[node];
    if (st != en) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  if (st >= l and en <= r) return tree[node];
  int mid = (st + en) / 2;
  pair<pair<long long, int>, int> ps = query(node * 2, st, mid, l, r);
  pair<pair<long long, int>, int> gs = query(node * 2 + 1, mid + 1, en, l, r);
  return min(ps, gs);
}
void pop_update(int node, int st, int en, int l) {
  if (lazy[node] != 0) {
    if (tree[node].second != 500000) tree[node].first.first += lazy[node];
    tottree[node] += lazy[node];
    if (st != en) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  if (st > l or en < l) return;
  if (st == en) {
    my[rev[l]].pop_back();
    int gs = my[rev[l]].size() - 1;
    tree[node] = my[rev[l]][gs];
    if (tree[node].second != 500000) tree[node].first.first += tottree[node];
    return;
  }
  int mid = (st + en) / 2;
  pop_update(node * 2, st, mid, l);
  pop_update(node * 2 + 1, mid + 1, en, l);
  tree[node] = min(tree[node * 2], tree[node * 2 + 1]);
}
pair<pair<long long, int>, int> make_up(int u, int v) {
  pair<pair<long long, int>, int> ps = bigdata;
  while (1) {
    if (chainno[u] == chainno[v]) {
      ps = min(ps, query(1, 1, cnt, pos[u], pos[v]));
      break;
    }
    int c = chainhead[chainno[v]];
    ps = min(ps, query(1, 1, cnt, pos[c], pos[v]));
    v = par[c][0];
  }
  return ps;
}
void update(int node, int st, int en, int l, int r, int v) {
  if (lazy[node] != 0) {
    if (tree[node].second != 500000) tree[node].first.first += lazy[node];
    tottree[node] += lazy[node];
    if (st != en) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  if (st > r or en < l) return;
  if (st >= l and en <= r) {
    if (tree[node].second != 500000) tree[node].first.first += v;
    tottree[node] += v;
    if (st != en) {
      lazy[node * 2] += v;
      lazy[node * 2 + 1] += v;
    }
    return;
  }
  int mid = (st + en) / 2;
  update(node * 2, st, mid, l, r, v);
  update(node * 2 + 1, mid + 1, en, l, r, v);
  tree[node] = min(tree[node * 2], tree[node * 2 + 1]);
}
void query(int u, int v, int k) {
  int lc = Lca_query(u, v);
  int ck = 0;
  pair<pair<long long, int>, int> gs, rs;
  vector<int> ans;
  while (k--) {
    gs = make_up(lc, v);
    rs = make_up(lc, u);
    gs = min(gs, rs);
    if (gs.second == 500000) break;
    ans.push_back(gs.second);
    pop_update(1, 1, cnt, pos[cv[gs.second]]);
  }
  printf("%d", ans.size());
  for (int i = 0; i < ans.size(); i++) {
    printf(" %d", ans[i]);
  }
  printf("\n");
}
void build(int node, int st, int en) {
  if (st == en) {
    int l = rev[st];
    tree[node] = my[l][my[l].size() - 1];
    return;
  }
  int mid = (st + en) / 2;
  build(node * 2, st, mid);
  build(node * 2 + 1, mid + 1, en);
  tree[node] = min(tree[node * 2], tree[node * 2 + 1]);
}
int main() {
  int i, j, k, l, m, n, q;
  scanf("%d%d%d", &n, &m, &q);
  memset(par, -1, sizeof par);
  for (int i = 1; i < n; i++) {
    scanf("%d%d", &l, &k);
    vc[l].push_back(k);
    vc[k].push_back(l);
  }
  for (int i = 1; i <= n; i++) {
    my[i].push_back(bigdata);
  }
  for (int i = 1; i <= m; i++) {
    scanf("%d", &l);
    my[l].push_back(make_pair(make_pair(i, l), i));
    cv[i] = l;
  }
  for (int i = 1; i <= n; i++) {
    sort(my[i].begin(), my[i].end());
    reverse(my[i].begin(), my[i].end());
  }
  dfs(1, -1, 0);
  hld(1, -1);
  build(1, 1, cnt);
  build(n);
  while (q--) {
    scanf("%d%d%d", &j, &l, &k);
    if (j == 2) {
      update(1, 1, cnt, st[l], en[l], k);
      continue;
    }
    scanf("%d", &i);
    query(l, k, i);
  }
}
