#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void checkmin(T &a, T b) {
  if (b < a) {
    a = b;
  }
}
template <typename T>
inline void checkmax(T &a, T b) {
  if (b > a) {
    a = b;
  }
}
const int maxn = (int)1e5 + 10;
const long long inf = (long long)1e18;
struct Node {
  long long w;
  int id, pos, segpos;
  long long add;
  Node(int id, int pos, int segpos, long long w, long long add)
      : id(id), pos(pos), segpos(segpos), w(w), add(add) {}
  Node() : id(0), pos(0), segpos(0), w(inf), add(0) {}
  bool operator<(const Node &o) const {
    return w == o.w ? pos < o.pos : w < o.w;
  }
};
inline ostream &operator<<(ostream &out, const Node &a) {
  out << a.id << ' ' << a.pos << ' ' << a.w;
  return out;
}
vector<Node> segs[maxn];
vector<int> partitions[maxn];
int tail[maxn];
int size[maxn], dep[maxn], fa[maxn], id[maxn], pos[maxn], idCnt;
int enter[maxn], leave[maxn], cnt;
long long totadd[maxn << 1];
vector<int> adj[maxn];
vector<Node> girls[maxn];
inline void getSummary(Node &a, Node &l, Node &r) {
  if (l < r) {
    a = Node(l.id, l.pos, l.segpos, l.w, a.add);
  } else {
    a = Node(r.id, r.pos, r.segpos, r.w, a.add);
  }
}
inline void push(Node &a, Node &l, Node &r) {
  if (a.add) {
    l.w += a.add;
    l.add += a.add;
    r.w += a.add;
    r.add += a.add;
    a.add = 0;
  }
}
void build(vector<Node> &seg, vector<int> &partition, int i, int l, int r) {
  if (l < r) {
    int mid = (l + r) / 2;
    build(seg, partition, i * 2, l, mid);
    build(seg, partition, i * 2 + 1, mid + 1, r);
    getSummary(seg[i], seg[i * 2], seg[i * 2 + 1]);
  } else {
    int p = partition[l];
    if (girls[p].size()) {
      seg[i] = girls[p].back();
      seg[i].segpos = l;
    } else {
      seg[i] = Node();
    }
  }
}
void remove(vector<Node> &seg, int i, int l, int r, int x) {
  if (l == r) {
    int p = seg[i].pos;
    long long k = seg[i].add;
    girls[p].pop_back();
    if (girls[p].size()) {
      seg[i] = girls[p].back();
      seg[i].w += k;
      seg[i].add = k;
      seg[i].segpos = l;
    } else {
      seg[i] = Node();
    }
  } else {
    int mid = (l + r) / 2;
    push(seg[i], seg[i * 2], seg[i * 2 + 1]);
    if (x <= mid) {
      remove(seg, i * 2, l, mid, x);
    } else {
      remove(seg, i * 2 + 1, mid + 1, r, x);
    }
    getSummary(seg[i], seg[i * 2], seg[i * 2 + 1]);
  }
}
void add(vector<Node> &seg, int i, int l, int r, int x, int y, int k) {
  if (x > r || y < l) {
    return;
  }
  if (x <= l && y >= r) {
    seg[i].w += k;
    seg[i].add += k;
  } else {
    int mid = (l + r) / 2;
    push(seg[i], seg[i * 2], seg[i * 2 + 1]);
    add(seg, i * 2, l, mid, x, y, k);
    add(seg, i * 2 + 1, mid + 1, r, x, y, k);
    getSummary(seg[i], seg[i * 2], seg[i * 2 + 1]);
  }
}
bool flag = false;
Node getBest(vector<Node> &seg, int i, int l, int r, int x, int y) {
  if (x > r || y < l) {
    return Node();
  }
  if (x <= l && y >= r) {
    return seg[i];
  } else {
    int mid = (l + r) / 2;
    push(seg[i], seg[i * 2], seg[i * 2 + 1]);
    return min(getBest(seg, i * 2, l, mid, x, y),
               getBest(seg, i * 2 + 1, mid + 1, r, x, y));
  }
}
void dfs(int u, int v) {
  fa[v] = u;
  dep[v] = dep[u] + 1;
  enter[v] = ++cnt;
  size[v] = 1;
  pair<int, int> prefer(0, 0);
  for (int w : adj[v]) {
    if (w != u) {
      dfs(v, w);
      size[v] += size[w];
      prefer = max(prefer, make_pair(size[w], w));
    }
  }
  int child = prefer.second;
  if (child != 0 && size[child] * 2 > size[v]) {
    id[v] = id[child];
  } else {
    id[v] = idCnt++;
  }
  pos[v] = partitions[id[v]].size();
  partitions[id[v]].emplace_back(v);
  leave[v] = ++cnt;
}
inline void add(int pos, int v) {
  while (pos <= cnt) {
    totadd[pos] += v;
    pos += pos & -pos;
  }
}
inline long long getsum(int pos) {
  long long res = 0;
  while (pos > 0) {
    res += totadd[pos];
    pos -= pos & -pos;
  }
  return res;
}
int main() {
  int n, m, q;
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].emplace_back(v);
    adj[v].emplace_back(u);
  }
  for (int i = 1; i <= m; ++i) {
    int c;
    scanf("%d", &c);
    girls[c].emplace_back(i, c, 0, i, 0);
  }
  for (int i = 1; i <= n; ++i) {
    sort((girls[i]).begin(), (girls[i]).end());
    reverse((girls[i]).begin(), (girls[i]).end());
  }
  dfs(0, 1);
  for (int i = 0; i < idCnt; ++i) {
    segs[i].resize(partitions[i].size() * 4);
    build(segs[i], partitions[i], 1, 0, partitions[i].size() - 1);
  }
  memset(totadd, 0, sizeof totadd);
  for (int i = 0; i < q; ++i) {
    int type, v, u, k;
    scanf("%d", &type);
    if (type == 1) {
      scanf("%d%d%d", &v, &u, &k);
      int _v = v;
      int _u = u;
      vector<int> res;
      for (int j = 0; j < k; ++j) {
        Node best, cur;
        v = _v;
        u = _u;
        while (true) {
          if (dep[partitions[id[v]].back()] < dep[partitions[id[u]].back()]) {
            swap(v, u);
          }
          if (id[v] == id[u]) {
            if (pos[v] > pos[u]) {
              swap(v, u);
            }
            cur = getBest(segs[id[v]], 1, 0, partitions[id[v]].size() - 1,
                          pos[v], pos[u]);
            cur.w += getsum(enter[fa[partitions[id[v]].back()]]);
            best = min(best, cur);
            break;
          } else {
            cur = getBest(segs[id[v]], 1, 0, partitions[id[v]].size() - 1,
                          pos[v], partitions[id[v]].size() - 1);
            cur.w += getsum(enter[fa[partitions[id[v]].back()]]);
            best = min(best, cur);
          }
          v = fa[partitions[id[v]].back()];
        }
        if (best.w >= inf) {
          break;
        }
        res.emplace_back(best.id);
        remove(segs[id[best.pos]], 1, 0, partitions[id[best.pos]].size() - 1,
               best.segpos);
      }
      printf("%d", res.size());
      for (int w : res) {
        printf(" %d", w);
      }
      puts("");
    } else {
      scanf("%d%d", &v, &k);
      add(enter[v], k);
      add(leave[v] + 1, -k);
      add(segs[id[v]], 1, 0, partitions[id[v]].size() - 1, 0, pos[v], k);
    }
  }
}
