#include <bits/stdc++.h>
using namespace std;
ifstream f("heavypath.in");
ofstream out("heavypath.out");
const int N = 1e5+5;
const int LG = log(N);
int n, q;
vector <int> g[N];
int numere[N];
int a[LG][N], nrnodarb[N];
int lg[N];
void cit()
{
for ( int i = 2 ; i <= N; i++ )
{
lg[i] = 1 + lg[(i/2)];
}
f >> n >> q;
for(int i = 1; i <= n; i++)
{
f >> numere[i];
}
for(int i = 1; i <= n - 1; i++)
{
int x, y;
f >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
}
int h[N];
void dfs(int nod, int tata)
{
int s = 0;
h[nod] = h[tata] + 1;
a[0][nod] = tata;
for(int i : g[nod])
{
if(a[0][i] != 0 || i == tata)
continue ;
dfs(i, nod);
s += nrnodarb[i];
}
nrnodarb[nod] = s + 1;
}
void prelca()
{
for(int i = 1; (1 << i) <= n; i++)
{
for(int j = 1; j <= n; j++)
a[i][j] = a[i - 1][a[i - 1][j]];
}
}
int lca(int x, int y)
{
int put = lg[h[x]];
if(x == y)
return x;
if(h[x] == h[y])
{
while( a[put][x] == a[put][y] && put > 0)
{
put--;
}
return lca(a[put][x], a[put][y]);
}
put = lg[abs(h[y] - h[x])];
if( h[x] > h[y])
{
return lca(a[put][x], y);
}
return lca(x, a[put][y]);
}
int fs(int nod)
{
return 2*nod;
}
int fd(int nod)
{
return 2*nod + 1;
}
struct aint{
vector <int> arb;
int nr_jos;
void upd(int st, int dr, int nod, int poz, int val)
{
if(st == dr)
{
arb[nod] = val;
return ;
}
int mij = (st + dr)/2;
if(poz <= mij)
upd(st, mij, fs(nod), poz, val);
else upd(mij + 1, dr, fd(nod), poz, val);
arb[nod] = max(arb[fs(nod)], arb[fd(nod)]);
}
int query(int st, int dr, int nod, int stx, int drx)
{
if( stx <= st && dr <= drx)
{
return arb[nod];
}
if( st > drx || stx > dr)
{
return INT_MIN;
}
int mij = (st + dr) /2;
return max(query(st, mij, fs(nod), stx, drx), query(mij + 1, dr, fd(nod), stx, drx));
}
void build(int st, int dr, int nod, vector<int>& v)
{
if ( st == dr )
{
arb[nod] = v[st];
return;
}
int mij = ( st + dr ) / 2;
build(st, mij, fs(nod), v);
build(mij+1, dr, fd(nod), v);
arb[nod] = max(arb[fs(nod)], arb[fd(nod)]);
}
int query(int st, int dr)
{
return query(1, nr_jos, 1, st, dr);
}
aint(vector<int>& v)
{
vector<int> aux;
aux.push_back(0);
for ( int x : v )
{
aux.push_back(numere[x]);
}
arb.resize(aux.size()*4);
nr_jos = aux.size() - 1;
build(1, aux.size() - 1, 1, aux);
}
void afisare(int nod, int st, int dr)
{
cout<<"Sunt pe intervalul ["<<st<<", "<<dr<<"] cu numarul "<<arb[nod]<<'\n';
if ( st == dr )
return;
int mij = ( st + dr ) / 2;
afisare(fs(nod), st, mij);
afisare(fd(nod), mij+1, dr);
}
void afisare()
{
afisare(1, 1, nr_jos);
}
void update(int poz, int val)
{
upd(1, nr_jos, 1, poz, val);
}
aint(){}
};
struct lant{
aint tree;
map <int, int> mp;
lant (vector <int>& v)
{
tree = aint(v);
for(int i = 0; i < v.size(); i++)
{
mp[v[i]] = i + 1;
}
}
void afiseaza()
{
tree.afisare();
}
};
vector <lant> lanturi;
map <int, int> mplant, lcap;
void hvy_light_comp(int nod, int tata,vector <int>& noduri_l)
{
int fiugr = 0;
for(int vec : g[nod])
{
if(vec == tata)
continue ;
if(nrnodarb[fiugr] < nrnodarb[vec])
fiugr = vec;
}
noduri_l.push_back(nod);
if(fiugr == 0)
{
lant l(noduri_l);
lcap [lanturi.size()] = noduri_l[0];
for(int x : noduri_l)
mplant[x] = lanturi.size();
lanturi.push_back(l);
return ;
}
hvy_light_comp(fiugr, nod, noduri_l);
for(int vec : g[nod])
{
if(vec == tata || vec == fiugr)
continue ;
vector <int> aux;
hvy_light_comp(vec, nod, aux);
}
}
void update(int nod, int val)
{
lanturi[mplant[nod]].tree.update(lanturi[mplant[nod]].mp[nod], val);
}
int queryup(int from, int to)
{
int ans = INT_MIN;
while ( mplant[from] != mplant[to] )
{
ans = max(ans, lanturi[mplant[from]].tree.query(lanturi[mplant[from]].mp[lcap[mplant[from]]], lanturi[mplant[from]].mp[from]));
from = a[0][lcap[mplant[from]]];
}
ans = max(ans, lanturi[mplant[from]].tree.query(
min(lanturi[mplant[from]].mp[from], lanturi[mplant[from]].mp[to]),
max(lanturi[mplant[from]].mp[from], lanturi[mplant[from]].mp[to])
));
return ans;
}
int query(int x, int y)
{
int aux = lca(x, y);
return max(queryup(x, aux),queryup(y, aux));
}
void rez()
{
dfs(1, 0);
prelca();
vector<int> aux;
hvy_light_comp(1, 0, aux);
for ( int i = 1 ; i <= q ; i++ )
{
int op, x, y;
f>>op>>x>>y;
if ( op == 0 )
{
update(x, y);
}
else
{
out<<query(x, y)<<'\n';
}
}
}
int main()
{
cit();
rez();
return 0;
}