#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int N = 100000,logn = 17;
int v[N],sub[N],cnt = 0;
pair <int,int> hpdp[N];
int endpoint[N];
int dpth[N];
vector <int> v2[N];
vector<int> seg[N];
vector<int> e[N];
int parent[logn][N];
void dfs(int node,int p = -1,int d = 0){
sub[node] = 1;
dpth[node] = d;
parent[0][node] = (p == -1?node:p);
for(auto i:e[node]){
if(i == p)continue;
dfs(i,node,d + 1);
sub[node]+=sub[i];
}
bool ok = 0;
for(auto i:e[node]){
if(i == p)continue;
if(sub[node]/2 <= sub[i]){
///heavy
ok = 1;
hpdp[node] = {hpdp[i].first,v2[hpdp[i].first].size()};
v2[hpdp[i].first].push_back(v[node]);
break;
}
}
if(!ok){
///new component
hpdp[node] = {cnt++,0};
v2[cnt - 1].push_back(v[node]);
}
}
void dfs2(int node,int p = -1){
if(p != -1 && hpdp[p].first == hpdp[node].first){
endpoint[node] = endpoint[p];
}else{
endpoint[node] = node;
}
for(auto i:e[node]){
if(i == p)continue;
dfs2(i,node);
}
}
int lca(int a,int b){
if(dpth[a] < dpth[b]){
swap(a,b);
}
for(int i = logn - 1;i >= 0;i--){
if(dpth[a] - (1<<i) >= dpth[b]){
a = parent[i][a];
}
}
for(int i = logn - 1;i >= 0;i--){
if(parent[i][a] != parent[i][b]){
a = parent[i][a];
b = parent[i][b];
}
}
if(a != b){
return parent[0][a];
}else return a;
}
void build(int id,int l,int r,int node = 1){
if(l == r){
seg[id][node] = v2[id][l];
}else{
int mij = (l + r)/2;
build(id,l,mij,node*2);
build(id,mij + 1,r,node*2 + 1);
seg[id][node] = max(seg[id][node*2],seg[id][node*2 + 1]);
}
}
void modify(int id,int target,int nr,int l,int r,int node = 1){
if(l == r){
v2[id][target] = nr;
seg[id][node] = nr;
}else{
int mij = (l + r)/2;
if(target <= mij){
modify(id,target,nr,l,mij,node*2);
}else{
modify(id,target,nr,mij + 1,r,node*2 + 1);
}
seg[id][node] = max(seg[id][node*2],seg[id][node*2 + 1]);
}
}
int query(int id,int l2,int r2,int l,int r,int node = 1){
if(l2 > r2)swap(l2,r2);
int nr = 0;
if(l2 <= l && r <= r2){
nr = seg[id][node];
}else{
int mij = (l + r)/2;
if(l2 <= mij)nr = max(nr,query(id,l2,r2,l,mij,node*2));
if(mij + 1 <= r2)nr = max(nr,query(id,l2,r2,mij + 1,r,node*2 + 1));
}
return nr;
}
int query2(int node,int p){
int ans = 0;
if(hpdp[node].first != hpdp[p].first){
///node -> endpoint
ans = query(hpdp[node].first,hpdp[node].second,hpdp[endpoint[node]].second,0,v2[hpdp[node].first].size() - 1);
ans = max(ans,query2(parent[0][endpoint[node]],p));
}else{
///node -> c
ans = query(hpdp[node].first,hpdp[node].second,hpdp[p].second,0,v2[hpdp[node].first].size() - 1);
}
return ans;
}
int main(){
int n,q,i,j,u,w,cer,a,b;
fin>>n>>q;
for(i = 0;i < n;i++){
fin>>v[i];
}
for(i = 0;i < n - 1;i++){
fin>>u>>w;
u--;w--;
e[u].push_back(w);
e[w].push_back(u);
}
dfs(0);
dfs2(0);
for(i = 1;i < logn;i++){
for(j = 0;j < n;j++){
parent[i][j] = parent[i - 1][parent[i - 1][j]];
}
}
for(i = 0;i < n;i++){
if(v2[i].size() == 0)continue;
seg[i].resize(v2[i].size()*4);
///build segment tree
build(i,0,v2[i].size() - 1);
}
for(i = 0;i < q;i++){
fin>>cer>>a>>b;
a--;b--;
if(cer == 1){
int c = lca(a,b);
fout<<max(query2(a,c),query2(b,c))<<'\n';;
}else{
b++;
v[a] = b;
v2[hpdp[a].first][hpdp[a].second] = b;
modify(hpdp[a].first,hpdp[a].second,b,0,v2[hpdp[a].first].size() - 1);
}
}
return 0;
}