#include <bits/stdc++.h>
using namespace std;
pair<int, int> minprof[1 << 20];
void inserta(int pos, pair<int, int> val) {
  pos += 1 << 19;
  minprof[pos] = val;
  while (pos > 1) {
    pos /= 2;
    minprof[pos] = min(minprof[2 * pos], minprof[2 * pos + 1]);
  }
}
int minimoentre(int pos0, int pos1) {
  if (pos0 > pos1) swap(pos0, pos1);
  pos0 += 1 << 19;
  pos1 += 1 << 19;
  if (pos0 == pos1) return minprof[pos0].second;
  pair<int, int> mini = min(minprof[pos0], minprof[pos1]);
  while (pos0 + 1 < pos1) {
    if (pos0 % 2 == 0) mini = min(mini, minprof[pos0 + 1]);
    pos0 /= 2;
    if (pos1 % 2 == 1) mini = min(mini, minprof[pos1 - 1]);
    pos1 /= 2;
  }
  return mini.second;
}
const int limite = 1000000;
const long long int infinito = 1000000000000000000LL;
struct elem {
  long long int ind, w;
  elem() {}
  elem(long long int ind, long long int w) : ind(ind), w(w) {}
};
int ind2u[limite];
bool operator<(elem e1, elem e2) {
  if (e1.w < e2.w) return true;
  if (e1.w > e2.w) return false;
  return ind2u[e1.ind] < ind2u[e2.ind];
}
elem operator+(elem e, long long int w) {
  e.w += w;
  return e;
}
void propaga(vector<elem> &minimo, vector<long long int> &anyade, int primero,
             int pos) {
  while (pos > 1) {
    pos /= 2;
    minimo[pos] = min(minimo[2 * pos], minimo[2 * pos + 1] + anyade[2 * pos]);
    anyade[pos] = anyade[2 * pos] + anyade[2 * pos + 1];
  }
}
void inserta(vector<elem> &minimo, vector<long long int> &anyade, int primero,
             int pos, elem e) {
  pos += primero;
  minimo[pos] = e + anyade[pos];
  propaga(minimo, anyade, primero, pos);
}
void anyadir(vector<elem> &minimo, vector<long long int> &anyade, int primero,
             int pos, long long int w) {
  pos += primero;
  anyade[pos] += w;
  minimo[pos].w += w;
  propaga(minimo, anyade, primero, pos);
}
elem minimoentre(vector<elem> &minimo, vector<long long int> &anyade,
                 int primero, int pos0, int pos1) {
  if (pos0 > pos1) swap(pos0, pos1);
  pos0 += primero;
  pos1 += primero;
  if (pos0 == pos1) return minimo[pos0];
  elem min0 = minimo[pos0];
  elem min1 = minimo[pos1];
  long long int any0 = anyade[pos0];
  while (pos0 + 1 < pos1) {
    if (pos0 % 2 == 0) {
      min0 = min(min0, minimo[pos0 + 1] + any0);
      any0 += anyade[pos0 + 1];
    }
    pos0 /= 2;
    if (pos1 % 2 == 1) min1 = min(minimo[pos1 - 1], min1 + anyade[pos1 - 1]);
    pos1 /= 2;
  }
  return min(min0, min1 + any0);
}
long long int anyadeentre(vector<elem> &minimo, vector<long long int> &anyade,
                          int primero, int pos0, int pos1) {
  if (pos0 > pos1) swap(pos0, pos1);
  pos0 += primero;
  pos1 += primero;
  if (pos0 == pos1) return anyade[pos0];
  long long int any = anyade[pos0] + anyade[pos1];
  while (pos0 + 1 < pos1) {
    if (pos0 % 2 == 0) any += anyade[pos0 + 1];
    pos0 /= 2;
    if (pos1 % 2 == 1) any += anyade[pos1 - 1];
    pos1 /= 2;
  }
  return any;
}
int n, m, q;
vector<int> g[limite];
int primero[limite];
int tope[limite];
vector<elem> minimo[limite];
vector<long long int> anyade[limite];
int identificador[limite];
int superpadre[limite];
int posicion[limite];
int numpos = 1;
int posle[limite];
int numnodos[limite];
vector<elem> pendiente[limite];
void anyadependiente(int u) {
  vector<elem> &pen = pendiente[u];
  int idu = identificador[u];
  int posu = posicion[u];
  if (int(pen.size()) == 0) {
    inserta(minimo[idu], anyade[idu], primero[idu], posu, elem(0, infinito));
    return;
  }
  inserta(minimo[idu], anyade[idu], primero[idu], posu, pen.back());
  pen.pop_back();
}
void eliminapadre(int u, int p, int prof) {
  vector<int> &ar = g[u];
  vector<int> nextar;
  posle[u] = numpos;
  inserta(numpos++, pair<int, int>(prof, u));
  numnodos[u] = 1;
  for (int i = 0; i < int(ar.size()); i++) {
    int v = ar[i];
    if (v != p) {
      nextar.push_back(v);
      eliminapadre(v, u, prof + 1);
      numnodos[u] += numnodos[v];
      inserta(numpos++, pair<int, int>(prof, u));
    }
  }
  ar = nextar;
}
void genera(int u, int sp) {
  vector<int> lista;
  lista.push_back(u);
  for (;;) {
    vector<int> &ar = g[u];
    int nextu = -1;
    for (int i = 0; i < int(ar.size()); i++) {
      int v = ar[i];
      if (numnodos[u] <= 2 * numnodos[v])
        nextu = v;
      else
        genera(v, u);
    }
    if (nextu == -1) break;
    u = nextu;
    lista.push_back(u);
  }
  u = lista[0];
  {
    int nn = int(lista.size()) + 2;
    primero[u] = 1;
    while (nn > 0) {
      nn /= 2;
      primero[u] *= 2;
    }
    tope[u] = 2 * primero[u];
  }
  minimo[u] = vector<elem>(tope[u], elem(0, infinito));
  anyade[u] = vector<long long int>(tope[u], 0);
  for (int i = 0; i < int(lista.size()); i++) {
    int v = lista[i];
    identificador[v] = u;
    superpadre[v] = sp;
    posicion[v] = i;
  }
}
struct info {
  int id, pos0, pos1;
  long long int suma;
  elem e;
  info() {}
  info(int id, int pos0, int pos1) : id(id), pos0(pos0), pos1(pos1) {
    suma = 0;
  }
};
void calculaelem(info &inf) {
  inf.e = minimoentre(minimo[inf.id], anyade[inf.id], primero[inf.id], inf.pos0,
                      inf.pos1);
}
long long int obtenerinfo(int u, int w, vector<info> &vinf) {
  int idu = identificador[u];
  int ind = int(vinf.size());
  if (idu == identificador[w]) {
    vinf.push_back(info(idu, posicion[u], posicion[w]));
    return anyadeentre(minimo[idu], anyade[idu], primero[idu], posicion[u],
                       posicion[w]);
  }
  vinf.push_back(info(idu, posicion[u], 0));
  long long int suma = obtenerinfo(superpadre[u], w, vinf);
  vinf[ind].suma = suma;
  return suma +
         anyadeentre(minimo[idu], anyade[idu], primero[idu], posicion[u], 0);
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m >> q;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  eliminapadre(1, 0, 0);
  genera(1, 0);
  for (int i = 1; i <= m; i++) {
    cin >> ind2u[i];
    pendiente[ind2u[i]].push_back(elem(i, i));
  }
  for (int u = 1; u <= n; u++) {
    vector<elem> &pen = pendiente[u];
    sort(pen.begin(), pen.end());
    reverse(pen.begin(), pen.end());
    anyadependiente(u);
  }
  for (int cas = 0; cas < q; cas++) {
    int tipo;
    cin >> tipo;
    if (tipo == 2) {
      long long int u, w;
      cin >> u >> w;
      int idu = identificador[u];
      anyadir(minimo[idu], anyade[idu], primero[idu], posicion[u], w);
    } else {
      int u, v, k;
      cin >> u >> v >> k;
      int w = minimoentre(posle[u], posle[v]);
      vector<info> vinf;
      obtenerinfo(u, w, vinf);
      obtenerinfo(v, w, vinf);
      vector<int> sol;
      for (; k > 0; k--) {
        for (int i = 0; i < int(vinf.size()); i++) calculaelem(vinf[i]);
        int imin = 0;
        for (int i = 0; i < int(vinf.size()); i++)
          if (vinf[i].e + vinf[i].suma < vinf[imin].e + vinf[imin].suma)
            imin = i;
        if (vinf[imin].e.ind == 0) break;
        sol.push_back(vinf[imin].e.ind);
        anyadependiente(ind2u[vinf[imin].e.ind]);
      }
      cout << int(sol.size());
      for (int i = 0; i < int(sol.size()); i++) cout << " " << sol[i];
      cout << endl;
    }
  }
}
