#include <fstream>
#include <algorithm>
#include <vector>
#define NM 100010
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int N, M, K;
int V[NM];
int WPath[NM], WPos[NM], Level[NM];
int PathSize[NM], PathFather[NM];
int PathLevel[NM];
int Delay[NM], Size[NM];
vector<int> G[NM];
int AI[8*NM];
int L, R, P, val;
void Update (int node, int delay, int S, int D)
{
if (S>=D)
{
AI[node + delay]=val;
return;
}
int M=(S+D)/2;
if (P<=M)
Update(2*node, delay, S, M);
else
Update(2*node+1, delay, M+1, D);
AI[node + delay] = max( AI[2*node + delay], AI[2*node+1 + delay]);
}
void Query (int node, int delay, int S, int D)
{
if (L<=S && D<=R)
{
val=max(val, AI[node + delay]);
return;
}
int M=(S+D)/2;
if (L<=M)
Query(2*node, delay, S, M);
if (R>M)
Query(2*node+1, delay, M+1, D);
}
void Read ()
{
f >> N >> M;
for (int i=1; i<=N; i++)
f >> V[i];
for (int i=1; i<N; i++)
{
int a, b;
f >> a >> b;
G[a].push_back(b);
G[b].push_back(a);
}
}
void DF (int node, int father)
{
int bigson=-1, bigsize=-1;
Size[node]=1;
Level[node]=1+Level[father];
for (vector<int>::iterator it=G[node].begin(); it!=G[node].end(); ++it)
{
if (*it==father)
continue;
DF(*it, node);
Size[node]+=Size[*it];
if (Size[*it]>bigsize)
{
bigsize=Size[*it];
bigson=*it;
}
}
if (bigson==-1)
{
++K;
WPath[node]=K;
WPos[node]=1;
PathSize[K]=1;
return;
}
WPath[node]=WPath[bigson];
PathSize[WPath[node]]++;
WPos[node]=PathSize[WPath[node]];
for (vector<int>::iterator it=G[node].begin(); it!=G[node].end(); ++it)
{
if (*it==father || *it==bigson)
continue;
PathFather[WPath[*it]]=node;
PathLevel[WPath[*it]]=Level[node];
}
}
void ComputeDelay ()
{
for (int i=1; i<=K; i++)
Delay[i]=Delay[i-1] + 4*PathSize[i-1] + 1;
}
void Build ()
{
for (int i=1; i<=N; i++)
{
P=WPos[i];
val=V[i];
Update(1, Delay[WPath[i]], 1, PathSize[WPath[i]]);
}
}
void GetANS (int x, int y)
{
val=0;
while (1)
{
if (PathLevel[WPath[x]]>PathLevel[WPath[y]])
swap(x, y);
if (WPath[x]==WPath[y])
{
L=min(WPos[x], WPos[y]);
R=max(WPos[x], WPos[y]);
Query(1, Delay[WPath[x]], 1, PathSize[WPath[x]]);
return;
}
L=WPos[y];
R=PathSize[WPath[y]];
Query(1, Delay[WPath[y]], 1, PathSize[WPath[y]]);
y=PathFather[WPath[y]];
}
}
void Solve ()
{
for (int i=1; i<=M; i++)
{
int t, x, y;
f >> t >> x >> y;
if (t==0)
{
P=WPos[x];
val=y;
Update(1, Delay[WPath[x]], 1, PathSize[WPath[x]]);
}
if (t==1)
{
GetANS(x, y);
g << val << '\n';
}
}
}
int main ()
{
Read();
DF(1, 0);
ComputeDelay();
Build();
Solve();
f.close();
g.close();
return 0;
}