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