#include <bits/stdc++.h>
using namespace std;
const int maxn = 300005;
using ll = long long;
ll inf = 1e18 + 7;
vector<int> edges[maxn];
int heavy[maxn], par[maxn], depth[maxn], sub[maxn];
int n, m, q;
int dfs(int x, int p) {
  int c_size = 1;
  int max_size = 0;
  par[x] = p;
  depth[x] = depth[p] + 1;
  sub[x] = 1;
  for (auto i : edges[x]) {
    if (i == p) continue;
    int sub_size = dfs(i, x);
    sub[x] += sub[i];
    c_size += sub_size;
    if (sub_size > max_size) {
      max_size = sub_size;
      heavy[x] = i;
    }
  }
  return c_size;
}
int head[maxn], pos[maxn], retrive[maxn];
int cnt = 0;
void decompose(int x, int p) {
  head[x] = p;
  pos[x] = ++cnt;
  retrive[cnt] = x;
  if (heavy[x] != 0) {
    decompose(heavy[x], p);
  }
  for (auto i : edges[x]) {
    if (i != heavy[x] && i != par[x]) {
      decompose(i, i);
    }
  }
}
int c[maxn];
vector<ll> g[maxn];
pair<ll, ll> t[maxn << 2];
ll lazy[maxn << 2];
void build(int node, int b, int e) {
  if (b == e) {
    t[node] = {0, retrive[b]};
    lazy[node] = 0;
    return;
  }
  int mid = (b + e) >> 1;
  build(2 * node, b, mid);
  build(2 * node + 1, mid + 1, e);
  t[node] = min(t[2 * node], t[2 * node + 1]);
  lazy[node] = 0;
}
void update(int node, int b, int e, int i, int j, ll val) {
  if (lazy[node] != 0) {
    t[node].first += lazy[node];
    if (b != e) {
      lazy[2 * node] += lazy[node];
      lazy[2 * node + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  if (i > e || j < b) return;
  if (b >= i && j >= e) {
    t[node].first += val;
    if (b != e) {
      lazy[2 * node] += val;
      lazy[2 * node + 1] += val;
    }
    return;
  }
  int mid = (b + e) >> 1;
  update(2 * node, b, mid, i, j, val);
  update(2 * node + 1, mid + 1, e, i, j, val);
  t[node] = min(t[2 * node], t[2 * node + 1]);
}
pair<ll, ll> query(int node, int b, int e, int i, int j) {
  if (lazy[node] != 0) {
    t[node].first += lazy[node];
    if (b != e) {
      lazy[2 * node] += lazy[node];
      lazy[2 * node + 1] += lazy[node];
    }
    lazy[node] = 0;
  }
  if (i > e || j < b) return {inf, -1};
  if (b >= i && j >= e) return t[node];
  int mid = (b + e) >> 1;
  pair<ll, int> p1 = query(2 * node, b, mid, i, j);
  pair<ll, int> p2 = query(2 * node + 1, mid + 1, e, i, j);
  return min(p1, p2);
}
pair<ll, ll> query(int a, int b) {
  pair<ll, ll> res = {inf, -1};
  while (head[a] != head[b]) {
    if (depth[head[a]] > depth[head[b]]) swap(a, b);
    res = min(res, query(1, 1, n, pos[head[b]], pos[b]));
    b = par[head[b]];
  }
  if (depth[a] > depth[b]) swap(a, b);
  res = min(res, query(1, 1, n, pos[a], pos[b]));
  return res;
}
int main(int argc, char const *argv[]) {
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 0; i < n - 1; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    edges[x].push_back(y);
    edges[y].push_back(x);
  }
  dfs(1, 1);
  decompose(1, 1);
  for (int i = 1; i <= m; i++) {
    scanf("%d", &c[i]);
    g[c[i]].push_back(i);
  }
  build(1, 1, n);
  vector<ll> last(n + 1);
  for (int i = 1; i <= n; i++) {
    if (g[i].empty()) {
      update(1, 1, n, pos[i], pos[i], inf);
      continue;
    } else {
      reverse(g[i].begin(), g[i].end());
      last[i] = g[i].back();
      g[i].pop_back();
      update(1, 1, n, pos[i], pos[i], last[i]);
    }
  }
  while (q--) {
    int t;
    scanf("%d", &t);
    if (t == 2) {
      int x;
      ll v;
      scanf("%d %lld", &x, &v);
      update(1, 1, n, pos[x], pos[x] + sub[x] - 1, v);
    } else {
      int a, b, k;
      scanf("%d %d %d", &a, &b, &k);
      vector<ll> v;
      while (k--) {
        pair<ll, ll> res = query(a, b);
        if (res.first >= inf) {
          break;
        }
        v.push_back(last[res.second]);
        if (g[res.second].empty()) {
          update(1, 1, n, pos[res.second], pos[res.second], inf);
        } else {
          update(1, 1, n, pos[res.second], pos[res.second],
                 g[res.second].back() - last[res.second]);
          last[res.second] = g[res.second].back();
          g[res.second].pop_back();
        }
      }
      printf("%d ", (int)v.size());
      for (auto i : v) printf("%lld ", i);
      printf("\n");
    }
  }
  return 0;
}
