#include <bits/stdc++.h>
using namespace std;
#define REP(i,a) for (int i = 0; i < a; i++)
#define FOR(i,a,b) for (int i = a; i <= b; i++)
#define ROF(i,a,b) for (int i = a; i >= b; i--)
#define FOREACH(it,x) for (auto it: (x))
#define pb push_back
#define SZ(x) ((int)(x).size())
const int Nmax = 100000;
int n,m;
int weight[Nmax+1];
int data[Nmax*4+5];
int val[Nmax+1];
vector<int> G[Nmax+1];
vector< vector<int> > chain;
int what_chain[Nmax+1];
int pos_in_chain[Nmax+1];
int pos_in_aint[Nmax+1];
int T[Nmax+1];
int lvl[Nmax+1];
void dfs(int node,int parent)
{
weight[node] = 1;
int best = -1;
FOREACH(it,G[node]) if (it != parent) {
lvl[it] = lvl[node] + 1; T[it] = node; dfs(it,node);
weight[node] += weight[it];
if (best == -1 || weight[best] < weight[it]) best = it;
}
if (best == -1) {
chain.pb(vector<int>());
chain.back().pb(node);
what_chain[node] = SZ(chain) - 1;
pos_in_chain[node] = 0;
}
else {
chain[what_chain[best]].pb(node);
what_chain[node] = what_chain[best];
pos_in_chain[node] = SZ(chain[what_chain[best]]) - 1;
}
}
void update(int node,int l,int r,int pos,int value)
{
if (l == r) {
data[node] = value;
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) update(node<<1,l,mid,pos,value);
else update(node<<1|1,mid+1,r,pos,value);
data[node] = max(data[node<<1],data[node<<1|1]);
}
int query(int node,int l,int r,int a,int b)
{
if (l > b || r < a) return -1;
if (l >= a && r <= b) return data[node];
int mid = (l + r) >> 1;
return max(query(node<<1,l,mid,a,b),query(node<<1|1,mid+1,r,a,b));
}
void buildHPD()
{
lvl[1] = 0;
dfs(1,-1);
int cpos = 0;
REP(i,SZ(chain)) {
REP(j,SZ(chain[i])) {
++cpos;
pos_in_aint[chain[i][j]] = cpos;
update(1,1,n,cpos,val[chain[i][j]]);
}
}
}
int QueryHPD(int x,int y)
{
int ret = 0;
while (what_chain[x] != what_chain[y]) {
if (lvl[chain[what_chain[x]].back()] < lvl[chain[what_chain[y]].back()]) swap(x,y);
ret = max(ret,query(1,1,n,pos_in_aint[x],pos_in_aint[chain[what_chain[x]].back()]));
x = T[chain[what_chain[x]].back()];
}
if (pos_in_aint[x] > pos_in_aint[y]) swap(x,y);
return max(ret,query(1,1,n,pos_in_aint[x],pos_in_aint[y]));
}
int main()
{
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
fin >> n >> m;
FOR(i,1,n) fin >> val[i];
FOR(i,1,n-1) {
int x,y;
fin >> x >> y;
G[x].pb(y),G[y].pb(x);
}
buildHPD();
FOR(i,1,m) {
int t,x,y; fin >> t >> x >> y;
if (t == 0) update(1,1,n,pos_in_aint[x],y);
else fout << QueryHPD(x,y) << "\n";
}
}