#include <bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define sz(a) (int)((a).size())
#define all(a) (a).begin(), (a).end()
#define lsb(x) (x & (-x))
#define vi vector<int>
#define YES { cout << "YES" << endl; return; }
#define NO { cout << "NO" << endl; return; }
using ll = long long;
using pii = std::pair<int, int>;
const int NMAX = 2e5;
const int LOG = 18;
using namespace std;
namespace Tree {
vector<int> T[NMAX + 5];
int up[NMAX + 5][LOG + 5];
int tin[NMAX + 5];
int tout[NMAX + 5];
int timer;
int N;
inline void add_edge(int u, int v) {
T[u].push_back(v);
T[v].push_back(u);
N = max({N, u, v});
}
void dfs(int nod, int p = 0) {
tin[nod] = ++timer;
up[nod][0] = p;
for (auto &son : T[nod]) {
if (son == p) continue;
dfs(son, nod);
}
tout[nod] = timer;
}
bool is_anc(int u, int v){
return (tin[u] <= tin[v] && tout[v] <= tout[u]);
}
void init() {
dfs(1);
for (int k = 1; k <= LOG; ++k) {
for (int u = 1; u <= N; ++u)
up[u][k] = up[up[u][k - 1]][k - 1];
}
}
inline int lca(int u, int v) {
if (is_anc(u, v)) return u;
if (is_anc(v, u)) return v;
for (int k = LOG; k >= 0; --k) {
if (up[u][k] && !is_anc(up[u][k], v))
u = up[u][k];
}
return up[u][0];
}
}
using namespace Tree;
set<pair<int, int>> two[NMAX + 5];
set<int> one[NMAX + 5];
int a[NMAX + 5], n, m, q;
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n >> m >> q;
for (int i = 0, u, v; i < n - 1; ++i) {
cin >> u >> v;
Tree::add_edge(u, v);
}
for (int i = 1; i <= m; ++i)
cin >> a[i];
Tree::init();
for (int i = 1; i <= m; ++i) {
one[a[i]].insert(i);
if (i > 1)
two[lca(a[i - 1], a[i])].insert({i - 1, i});
}
for (int i = 0, op, l, r, pos, v; i < q; ++i) {
cin >> op;
if (op == 1) {
cin >> pos >> v;
one[a[pos]].erase(pos);
if (pos > 1)
two[lca(a[pos - 1], a[pos])].erase({pos - 1, pos});
a[pos] = v;
one[a[pos]].insert(pos);
if (pos > 1)
two[lca(a[pos - 1], a[pos])].insert({pos - 1, pos});
}
if (op == 2) {
cin >> l >> r >> v;
auto it = one[v].lower_bound(l);
if (it != one[v].end() && *it <= r) {
cout << *it << ' ' << *it << '\n';
continue;
}
auto it2 = two[v].lower_bound({l, 0});
if (it2 != two[v].end() && it2->se <= r) {
cout << it2->fi << ' ' << it2->se << '\n';
continue;
}
cout << "-1 -1\n";
}
}
return 0;
}