#include <fstream>
#include <vector>
#define VAL 100005
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int N, M, i, j, A, B, NRL, mx, son, nr, T, X, Y, cop, ANS, be, en;
int elem[VAL], niv[VAL], lant[VAL], poz[VAL], subarb[VAL], fat[VAL];
bool par[VAL];
vector <int> G[VAL], L[VAL], AINT[VAL];
vector <int> :: iterator it;
void DFS(int nod)
{
int mx, son;
vector <int> :: iterator it;
nr=0;
subarb[nod]++;
par[nod]=true;
for (it=G[nod].begin(); it!=G[nod].end(); it++)
if (par[*it]==false)
nr++;
if (nr==0)
{
NRL++;
L[NRL].push_back(0);
L[NRL].push_back(nod);
lant[nod]=NRL;
poz[nod]=L[NRL].size()-1;
return;
}
mx=son=0;
for (it=G[nod].begin(); it!=G[nod].end(); it++)
{
if (par[*it]==true)
continue;
niv[*it]=niv[nod]+1;
fat[*it]=nod;
DFS(*it);
if (mx<subarb[*it])
{
mx=subarb[*it];
son=*it;
}
subarb[nod]+=subarb[*it];
}
L[lant[son]].push_back(nod);
lant[nod]=lant[son];
poz[nod]=L[lant[nod]].size()-1;
}
void Initializare(int nod, int be, int en)
{
if (be==en)
AINT[i][nod]=elem[L[i][be]];
else
{
int mid=(be+en) / 2;
Initializare(2*nod, be, mid);
Initializare(2*nod+1, mid+1, en);
AINT[i][nod]=max(AINT[i][2*nod], AINT[i][2*nod+1]);
}
}
void Update(int l, int nod, int be, int en, int poz)
{
if (be==en)
AINT[l][nod]=elem[L[l][be]]=Y;
else
{
int mid=(be+en) / 2;
if (be<=poz && poz<=mid)
Update(l, 2*nod, be, mid, poz);
if (mid+1<=poz && poz<=en)
Update(l, 2*nod+1, mid+1, en, poz);
AINT[l][nod]=max(AINT[l][2*nod], AINT[l][2*nod+1]);
}
}
void Query(int l, int nod, int be, int en, int st, int dr)
{
if (st<=be && en<=dr)
{
ANS=max(ANS, AINT[l][nod]);
return;
}
int mid=(be+en) / 2;
if (max(be, st)<=min(mid, dr))
Query(l, 2*nod, be, mid, st, dr);
if (max(mid+1, st)<=min(en, dr))
Query(l, 2*nod+1, mid+1, en, st, dr);
}
int main()
{
fin >> N >> M;
for (i=1; i<=N; i++)
fin >> elem[i];
for (i=1; i<N; i++)
{
fin >> A >> B;
G[A].push_back(B);
G[B].push_back(A);
}
niv[1]=1;
DFS(1);
for (i=1; i<=NRL; i++)
{
cop=1;
while (cop<2*L[i].size()-3)
cop*=2;
AINT[i].push_back(cop);
for (j=1; j<=cop; j++)
AINT[i].push_back(0);
Initializare(1, 1, L[i].size()-1);
for (j=1; j<L[i].size(); j++)
poz[L[i][j]]=j;
}
for (i=1; i<=M; i++)
{
fin >> T >> X >> Y;
if (T==0)
Update(lant[X], 1, 1, L[lant[X]].size()-1, poz[X]);
else
{
ANS=0;
while (lant[X]!=lant[Y])
{
if (L[lant[X]].size()<L[lant[Y]].size())
{
be=poz[X];
en=L[lant[X]].size()-1;
// Query(lant[X], 1, 1, L[lant[X]].size()-1, be, en);
X=L[lant[X]][en];
X=fat[X];
}
else
{
be=poz[Y];
en=L[lant[Y]].size()-1;
// Query(lant[Y], 1, 1, L[lant[Y]].size()-1, be, en);
Y=L[lant[Y]][en];
Y=fat[Y];
}
}
be=min(poz[X], poz[Y]);
en=max(poz[X], poz[Y]);
//Query(lant[X], 1, 1, L[lant[X]].size()-1, be, en);
fout << ANS << '\n';
}
}
fin.close();
fout.close();
return 0;
}