#include<algorithm>
#include<fstream>
#include<vector>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int const N = 1e5 + 3;
int n , m , a , b;
int t[N] , d[N] , mx[N] , fiu[N] , sz[N] , val[N];
vector<int> v[N];
void dfs(int x , int tx = -1){
sz[x] = 1;
for(int y : v[x]){
if(y == tx)
continue;
d[y] = 1 + d[x];
t[y] = x;
dfs(y , x);
sz[x] += sz[y];
if(sz[y] > sz[fiu[x]]){
mx[x] = y;
fiu[x] = y;
}
}
}
struct aint{
int M;
vector<int> t;
aint(){}
aint(int _M) : M(_M) , t(2 * M , 0){}
void update(int p , int val){
t[p += M - 1] = val;
for(p >>= 1 ; p ; p >>= 1)
t[p] = max(t[p * 2] , t[p * 2 + 1]);
}
int query(int l , int r){
int res(0);
for(l += M - 1 , r += M ; l < r ; l >>= 1 , r >>= 1){
if(l & 1)
res = max(res , t[l++]);
if(r & 1)
res = max(res , t[--r]);
}
return res;
}
};
int rt[N] , l[N] , dl[N] , nrl;
vector<int> L[30];
inline int pos(int x){
return d[x] - d[rt[l[x]]] + 1;
}
void dfs2(int x , int t = -1 , bool nou = true , int lnt = 1 , int adl = 0){
if(nou){
lnt = ++nrl;
rt[lnt] = x;
}
dl[lnt] = adl;
l[x] = lnt;
L[lnt].push_back(x);
for(int y : v[x]){
if(y == t)
continue;
if(y == fiu[x])
dfs2(y , x , false , lnt , adl);
else
dfs2(y , x , true , -1 , adl + 1);
}
}
int root;
vector<aint> T;
int query(int x , int y){
if(l[x] == l[y]){
if(pos(x) > pos(y))
swap(x , y);
return T[l[x]].query(pos(x) , pos(y));
}
if(dl[l[x]] > dl[l[y]])
swap(x , y);
int res = 0;
while(dl[l[y]] > dl[l[x]]){
res = max(res , T[l[y]].query(1 , pos(y)));
y = t[rt[l[y]]];
}
if(l[x] == l[y])
return max(res , query(x , y));
while(l[x] != l[y]){
res = max(res , T[l[x]].query(1 , pos(x)));
res = max(res , T[l[y]].query(1 , pos(y)));
y = t[rt[l[y]]];
x = t[rt[l[x]]];
}
return max(res , query(x , y));
}
int main(){
fin >> n >> m;
for(int i = 1 ; i <= n ; ++ i){
fin >> val[i];
}
for(int i = 1 ; i < n ; ++ i){
fin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
}
dfs(1);
dfs2(1);
T.push_back(aint());
for(int i = 1 ; i <= nrl ; ++ i){
aint nt(L[i].size());
for(int j = 0 ; j < L[i].size() ; ++ j)
nt.update(j + 1 , val[L[i][j]]);
T.push_back(nt);
}
for(int i = 1 ; i <= m ; ++ i){
int tp , x , y;
fin >> tp >> x >> y;
if(tp){
fout << query(x , y) << '\n';
}else{
T[l[x]].update(pos(x) , y);
}
}
return 0;
}