#include <fstream>
#include <vector>
#include <algorithm>
#define nMax 100001
#define pb push_back
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n, nrQuery, nrLanturi;
int arb[4*nMax], whatPath[nMax], sons[nMax], viz[nMax], pozLant[nMax], dimLant[nMax], v[nMax], lev[nMax], tataLant[nMax], levTataLant[nMax];
vector<int> noduriLant[nMax], G[nMax];
void build(int node, int st, int dr, int decalaj, int lant)
{
if(st==dr)
{
arb[node+decalaj]=v[noduriLant[lant][st-1]];
return;
}
int mid=st+(dr-st)/2;
build(2*node, st, mid, decalaj, lant);
build(2*node+1, mid+1, dr, decalaj, lant);
arb[node+decalaj]=max(arb[2*node+decalaj], arb[2*node+1+decalaj]);
}
void upDate(int node, int st, int dr, int decalaj, int poz, int val)
{
if(st==dr)
{
arb[node+decalaj]=val;
return;
}
int mid=st+(dr-st)/2;
if(poz<=mid)
upDate(2*node, st, mid, decalaj, poz, val);
else
upDate(2*node+1, mid+1, dr, decalaj, poz, val);
arb[node+decalaj]=max(arb[2*node+decalaj], arb[2*node+1+decalaj]);
}
void dfs(int node)
{
viz[node]=1;
sons[node]=1;
int frunza=1, fiuLantMax=-1;
for(vector<int>::iterator it=G[node].begin(); it!=G[node].end(); it++)
{
int fiu=*it;
if(viz[fiu])
continue;
frunza=0;
lev[fiu]=lev[node]+1;
dfs(fiu);
sons[node]+=sons[fiu];
if(fiuLantMax==-1)
fiuLantMax=fiu;
else
if(sons[fiuLantMax]<sons[fiu])
fiuLantMax=fiu;
}
if(frunza)
{
whatPath[node]=++nrLanturi;
dimLant[nrLanturi]++;
noduriLant[nrLanturi].pb(node);
return;
}
whatPath[node]=whatPath[fiuLantMax];
dimLant[whatPath[node]]++;
noduriLant[whatPath[node]].pb(node);
for(vector<int>::iterator it=G[node].begin(); it!=G[node].end(); it++)
{
int fiu=*it;
if(fiu==fiuLantMax || lev[fiu]<lev[node])
continue;
tataLant[whatPath[fiu]]=node;
levTataLant[whatPath[fiu]]=lev[node];
}
}
int query(int node, int st, int dr, int pozst, int pozdr, int decalaj)
{
int Sol=0;
if(st>=pozst && dr<=pozdr)
return arb[node+decalaj];
int mid=st+(dr-st)/2;
if(pozst<=mid)
Sol=max(Sol, query(2*node, st, mid, pozst, pozdr, decalaj));
if(pozdr>mid)
Sol=max(Sol, query(2*node+1, mid+1, dr, pozst, pozdr, decalaj));
return Sol;
}
int main()
{
int a, b;
fin>>n>>nrQuery;
for(int i=1; i<=n; i++)
fin>>v[i];
for(int i=1; i<n; i++)
{
fin>>a>>b;
G[a].pb(b);
G[b].pb(a);
}
lev[1]=1;
dfs(1);
for(int i=1; i<=nrLanturi; i++)
{
reverse(noduriLant[i].begin(), noduriLant[i].end());
if(i>1)
pozLant[i]=pozLant[i-1]+dimLant[i-1]*4;
build(1, 1, dimLant[i], pozLant[i], i);
}
for(int i=1; i<=nrQuery; i++)
{
int op, x, y;
fin>>op>>x>>y;
if(op==0)
upDate(1, 1, dimLant[whatPath[x]], pozLant[whatPath[x]], lev[x]-levTataLant[whatPath[x]], y);
else
{
int Sol=0;
while(whatPath[x]!=whatPath[y])
{
if(levTataLant[whatPath[x]]>levTataLant[whatPath[y]])
swap(x, y);
Sol=max(Sol, query(1, 1, dimLant[whatPath[y]], 1, lev[y]-levTataLant[whatPath[y]], pozLant[whatPath[y]]));
y=tataLant[whatPath[y]];
}
if(lev[x]>lev[y])
swap(x, y);
Sol=max(Sol, query(1, 1, dimLant[whatPath[x]], lev[x]-levTataLant[whatPath[x]], lev[y]-levTataLant[whatPath[x]], pozLant[whatPath[y]]));
fout<<Sol<<'\n';
}
}
}