#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chkmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T>
inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
const int oo = 0x3f3f3f3f;
const int __buffsize = 100000;
char __buff[__buffsize];
char *__buffs, *__buffe;
template <typename T>
inline T &Read(T &first) {
  static char c;
  while (1) {
    c = (__buffs == __buffe ? fread(__buff, 1, __buffsize, stdin),
         __buffe = __buff + __buffsize, *((__buffs = __buff)++) : *(__buffs++));
    if (c == '-' || (c >= '0' && c <= '9')) break;
  }
  bool flag = c == '-';
  first = flag ? 0 : c - '0';
  while (1) {
    c = (__buffs == __buffe ? fread(__buff, 1, __buffsize, stdin),
         __buffe = __buff + __buffsize, *((__buffs = __buff)++) : *(__buffs++));
    if (c < '0' || c > '9') break;
    (first *= 10) += c - '0';
  }
  if (flag) first = -first;
  return first;
}
const int maxn = 100100, maxm = 100100;
struct edge {
  int id, nxt;
  edge() {}
  edge(int _id, int _nxt) : id(_id), nxt(_nxt) {}
};
edge e[(maxn << 1) + 5];
int st[maxn + 5], en = 0;
inline void add_edge(int first, int second) {
  e[en] = edge(second, st[first]), st[first] = en++;
}
inline void add_biedge(int first, int second) {
  add_edge(first, second), add_edge(second, first);
}
int n, m, qn;
int fa[maxn + 5];
int sz[maxn + 5], Max[maxn + 5], cur[maxn + 5];
int dfs_seq[maxn + 5], dfs_tot;
int dep[maxn + 5];
void dfs(int first) {
  fa[first] = -1;
  dep[first] = 0;
  int u = first;
  bool flag = 0;
  while (u != -1) {
    if (!flag) {
      dfs_seq[dfs_tot++] = u;
      sz[u] = 1;
      Max[u] = -1;
      cur[u] = st[u];
      flag = 1;
    }
    for (int &i = cur[u]; i != -1; i = e[i].nxt) {
      const int &v = e[i].id;
      if (v == fa[u]) continue;
      dep[v] = dep[u] + 1;
      fa[v] = u;
      u = v;
      i = e[i].nxt;
      flag = 0;
      break;
    }
    if (flag) {
      int v = u;
      u = fa[u];
      if (u != -1) {
        sz[u] += sz[v];
        if (Max[u] == -1 || sz[v] > sz[Max[u]]) Max[u] = v;
      }
    }
  }
}
int hseq[maxn + 5];
int dfn[maxn + 5], End[maxn + 5];
int tot = 0;
void heavy_first_dfs(int first) {
  hseq[dfn[first] = tot++] = first;
  if (Max[first] != -1) heavy_first_dfs(Max[first]);
  for (int i = st[first]; i != -1; i = e[i].nxt) {
    int second = e[i].id;
    if (second == fa[first] || second == Max[first]) continue;
    heavy_first_dfs(second);
  }
  End[first] = tot;
}
int now;
int c[maxm + 5];
inline void upd(pair<long long, int> &a, const pair<long long, int> &b) {
  if (a.first > b.first)
    a = b;
  else if (a.first == b.first && ~a.second && c[b.second] < c[a.second])
    a = b;
}
struct node {
  node *c[2];
  pair<long long, int> Min;
  long long label;
  node() : Min(make_pair(LLONG_MAX, -1)) { memset(c, 0, sizeof c); }
  void update() {
    Min = make_pair(LLONG_MAX, -1);
    for (int i = (0), i_end_ = (2); i < i_end_; ++i)
      if (c[i]) upd(Min, c[i]->Min);
  }
  void flag_label(const long long &_label) {
    label += _label;
    if (Min.first != LLONG_MAX) Min.first += _label;
  }
  void push_down() {
    if (label) {
      for (int i = (0), i_end_ = (2); i < i_end_; ++i)
        if (c[i]) c[i]->flag_label(label);
      label = 0;
    }
  }
};
const int max0 = 100000;
node *nd_pool;
int nd_res = 0;
node *newnode() {
  if (!nd_res) nd_pool = new node[max0], nd_res = max0;
  return nd_pool + (--nd_res);
}
int seg_x, seg_y, seg_z;
long long seg_delta;
pair<long long, int> seg_ret;
vector<int> all[maxn + 5];
void build(node *&rt, int l, int r) {
  if (!rt) rt = newnode();
  if (r - l <= 1) {
    if (all[hseq[l]].empty())
      rt->Min = make_pair(LLONG_MAX, -1);
    else
      rt->Min = make_pair(all[hseq[l]].back(), all[hseq[l]].back());
    return;
  }
  int mid = (l + r) >> 1;
  build(rt->c[0], l, mid);
  build(rt->c[1], mid, r);
  rt->update();
}
void add(node *rt, int l, int r) {
  if (seg_x <= l && r <= seg_y) {
    rt->flag_label(seg_z);
    return;
  }
  int mid = (l + r) >> 1;
  rt->push_down();
  if (seg_x < mid) add(rt->c[0], l, mid);
  if (seg_y > mid) add(rt->c[1], mid, r);
  rt->update();
}
void del(node *rt, int l, int r) {
  if (r - l <= 1) {
    if (seg_delta == LLONG_MAX)
      rt->Min.first = LLONG_MAX;
    else
      rt->Min.first += seg_delta;
    rt->Min.second = all[hseq[l]].empty() ? -1 : all[hseq[l]].back();
    return;
  }
  int mid = (l + r) >> 1;
  rt->push_down();
  if (seg_x < mid)
    del(rt->c[0], l, mid);
  else
    del(rt->c[1], mid, r);
  rt->update();
}
void query(node *&rt, int l, int r) {
  if (seg_x <= l && r <= seg_y) {
    upd(seg_ret, rt->Min);
    return;
  }
  int mid = (l + r) >> 1;
  rt->push_down();
  if (seg_x < mid) query(rt->c[0], l, mid);
  if (seg_y > mid) query(rt->c[1], mid, r);
}
node *rt;
int top[maxn + 5];
inline int lca(int first, int second) {
  while (top[first] != top[second]) {
    if (dep[top[first]] > dep[top[second]]) swap(first, second);
    second = fa[top[second]];
  }
  return dep[first] < dep[second] ? first : second;
}
inline void query(int first, int second) {
  int d = lca(first, second);
  seg_z = 1;
  while (1) {
    int nxt = dep[top[first]] < dep[d] ? d : top[first];
    seg_x = dfn[nxt];
    seg_y = dfn[first] + 1;
    query(rt, 0, n);
    if (nxt == d) break;
    first = fa[nxt];
  }
  while (1) {
    int nxt = dep[top[second]] < dep[d] ? d : top[second];
    seg_x = dfn[nxt];
    seg_y = dfn[second] + 1;
    query(rt, 0, n);
    if (nxt == d) break;
    second = fa[nxt];
  }
}
int main() {
  memset(st, -1, sizeof st), en = 0;
  Read(n), Read(m), Read(qn);
  for (int i = (0), i_end_ = (n - 1); i < i_end_; ++i) {
    int u, v;
    Read(u), Read(v), --u, --v;
    add_biedge(u, v);
  }
  for (int i = (0), i_end_ = (m); i < i_end_; ++i) Read(c[i]), --c[i];
  for (int i = m - 1; i >= 0; --i) all[c[i]].push_back(i);
  dfs(0);
  top[0] = 0;
  for (int i = (1), i_end_ = (n); i < i_end_; ++i)
    if (sz[dfs_seq[i]] && Max[fa[dfs_seq[i]]] == dfs_seq[i])
      top[dfs_seq[i]] = top[fa[dfs_seq[i]]];
    else
      top[dfs_seq[i]] = dfs_seq[i];
  heavy_first_dfs(0);
  build(rt, 0, n);
  for (int i = (0), i_end_ = (qn); i < i_end_; ++i) {
    int ty;
    Read(ty);
    if (ty == 1) {
      int u, v, K;
      Read(u), Read(v), Read(K);
      --u, --v;
      vector<int> ans;
      while (K--) {
        seg_ret = make_pair(LLONG_MAX, -1);
        query(u, v);
        if (!~seg_ret.second) break;
        ans.push_back(seg_ret.second);
        seg_x = dfn[c[seg_ret.second]];
        vector<int> &tmp = all[c[seg_ret.second]];
        tmp.pop_back();
        if (tmp.empty())
          seg_delta = LLONG_MAX;
        else
          seg_delta = tmp.back() - seg_ret.second;
        del(rt, 0, n);
      }
      printf("%d", (int((ans).size())));
      for (auto first : ans) printf(" %d", first + 1);
      printf("\n");
    } else if (ty == 2) {
      int u, K;
      Read(u), Read(K), --u;
      seg_x = dfn[u], seg_y = End[u], seg_z = K;
      add(rt, 0, n);
    }
  }
  return 0;
}
