#include <bits/stdc++.h>
#pragma warning(disable : 4996)
template <typename T>
T min(T x, T y) {
  return x < y ? x : y;
}
template <typename T>
T max(T x, T y) {
  return x > y ? x : y;
};
const long long INF = 10000000000000000;
const long long MAXN = 100005;
struct tree {
  long long l;
  long long r;
  std::pair<long long, long long> mn;
  long long tag;
  tree *lson;
  tree *rson;
  tree() {
    l = r = tag = mn.first = mn.second = 0;
    lson = rson = NULL;
  }
  void fixup() { mn = std::min(lson->mn, rson->mn); }
  void ADD(long long k) {
    mn.first += k;
    tag += k;
  }
  void pushdown() {
    if (tag) {
      lson->ADD(tag);
      rson->ADD(tag);
      tag = 0;
    }
  }
  void build(long long L, long long R) {
    l = L;
    r = R;
    if (l == r) {
      mn.first = INF;
      mn.second = l;
      return;
    }
    long long mid = (l + r) / 2;
    lson = new tree;
    rson = new tree;
    lson->build(l, mid);
    rson->build(mid + 1, r);
    fixup();
  }
  void update(long long id, long long k) {
    if (l == r) {
      mn.first = k;
      return;
    }
    pushdown();
    long long mid = (l + r) / 2;
    if (id <= mid)
      lson->update(id, k);
    else
      rson->update(id, k);
    fixup();
  }
  void modify(long long L, long long R, long long k) {
    if (l >= L && r <= R) {
      ADD(k);
      return;
    }
    pushdown();
    long long mid = (l + r) / 2;
    if (L <= mid) lson->modify(L, R, k);
    if (R > mid) rson->modify(L, R, k);
    fixup();
  }
  std::pair<long long, long long> query(long long L, long long R) {
    if (l >= L && r <= R) return mn;
    pushdown();
    long long mid = (l + r) / 2;
    if (R <= mid) return lson->query(L, R);
    if (L > mid) return rson->query(L, R);
    return std::min(lson->query(L, R), rson->query(L, R));
  }
};
struct Ftree {
  long long bit[MAXN];
  void modify(long long L, long long R, long long k) {
    for (long long i = L; i < MAXN; i += i & -i) bit[i] += k;
    for (long long i = R + 1; i < MAXN; i += i & -i) bit[i] -= k;
  }
  long long query(long long id) {
    long long ret = 0;
    for (long long i = id; i; i -= i & -i) ret += bit[i];
    return ret;
  }
};
struct node {
  long long to;
  node *next;
};
void addnode(node *&head, long long to) {
  node *p = new node;
  p->to = to;
  p->next = head;
  head = p;
}
long long N, M, Q;
std::vector<long long> id[MAXN];
long long cur[MAXN];
node *edge[MAXN];
long long size[MAXN], fa[MAXN], dep[MAXN], son[MAXN];
long long top[MAXN], rank[MAXN], end[MAXN], ori[MAXN];
tree T;
Ftree FT;
void dfs1(long long v) {
  size[v] = 1;
  dep[v] = dep[fa[v]] + 1;
  for (node *p = edge[v]; p; p = p->next) {
    if (p->to == fa[v]) continue;
    fa[p->to] = v;
    dfs1(p->to);
    size[v] += size[p->to];
    if (size[p->to] > size[son[v]]) son[v] = p->to;
  }
}
long long dfs_clock;
void dfs2(long long v, long long t) {
  top[v] = t;
  rank[v] = ++dfs_clock;
  ori[dfs_clock] = v;
  if (son[v]) dfs2(son[v], t);
  for (node *p = edge[v]; p; p = p->next)
    if (p->to != fa[v] && p->to != son[v]) dfs2(p->to, p->to);
  end[v] = dfs_clock;
}
long long LCA(long long x, long long y) {
  if (top[x] == top[y]) return dep[x] < dep[y] ? x : y;
  if (dep[top[x]] > dep[top[y]]) return LCA(fa[top[x]], y);
  return LCA(x, fa[top[y]]);
}
void init() {
  long long u, v;
  scanf("%I64d %I64d %I64d", &N, &M, &Q);
  for (long long i = 1; i < N; i++) {
    scanf("%I64d %I64d", &u, &v);
    addnode(edge[u], v);
    addnode(edge[v], u);
  }
  dfs1(1);
  dfs2(1, 1);
  T.build(1, N);
  for (long long i = 1; i <= M; i++) {
    scanf("%I64d", &u);
    id[u].push_back(i);
    if (id[u].size() == 1) T.update(rank[u], i);
  }
}
long long select(long long u, long long v) {
  long long lca = LCA(u, v);
  std::pair<long long, long long> tp = std::make_pair(INF, INF);
  while (top[u] != top[lca]) {
    tp = std::min(tp, T.query(rank[top[u]], rank[u]));
    u = fa[top[u]];
  }
  tp = std::min(tp, T.query(rank[lca], rank[u]));
  while (top[v] != top[lca]) {
    tp = std::min(tp, T.query(rank[top[v]], rank[v]));
    v = fa[top[v]];
  }
  tp = std::min(tp, T.query(rank[lca], rank[v]));
  if (tp.first > INF / 10) return 0;
  long long pos = ori[tp.second];
  cur[pos]++;
  if (cur[pos] < id[pos].size())
    T.update(rank[pos], id[pos][cur[pos]] + FT.query(rank[pos]));
  else
    T.update(rank[pos], INF);
  return tp.first - FT.query(rank[pos]);
}
void opt2(long long r, long long k) {
  T.modify(rank[r], end[r], k);
  FT.modify(rank[r], end[r], k);
}
void solve() {
  long long ty, u, v, k;
  for (long long i = 0; i < Q; i++) {
    scanf("%I64d", &ty);
    if (ty == 1) {
      scanf("%I64d %I64d %I64d", &u, &v, &k);
      std::vector<long long> tmp;
      while (k--) {
        long long t = select(u, v);
        if (t)
          tmp.push_back(t);
        else
          break;
      }
      printf("%u ", tmp.size());
      for (long long i = 0; i < tmp.size(); i++) printf("%I64d ", tmp[i]);
      printf("\n");
    } else {
      scanf("%I64d %I64d", &u, &k);
      opt2(u, k);
    }
  }
}
int main() {
  init();
  solve();
  return 0;
}
