#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
const int inf = INT_MAX;
const int matrix_size = 2;
int n, m;
int head[maxn], nxt[maxn], to[maxn], tot;
void add(int u, int v) {
to[++tot] = v;
nxt[tot] = head[u];
head[u] = tot;
}
int siz[maxn], son[maxn], top[maxn], fa[maxn], dep[maxn], dfn[maxn], id[maxn], ed[maxn];
int idx;
int a[maxn], f[maxn][2];
struct matrix {
int g[matrix_size][matrix_size];
matrix() {
memset(g, 0, sizeof(g));
} matrix operator*(const matrix&b)const {
matrix sum;
for (int i = 0; i <= 1; i++) {
for (int j = 0; j <= 1; j++) {
for (int k = 0; k <= 1; k++) {
sum.g[i][j] = max(sum.g[i][j], g[i][k] + b.g[k][j]);
}
}
}
return sum;
}
} tree[maxn], g[maxn];
int ls(int o) {
return o << 1;
}
int rs(int o) {
return o << 1 | 1;
}
void push_up(int rt) {
tree[rt] = tree[ls(rt)] * tree[rs(rt)];
}
void build(int rt, int l, int r) {
if (l == r) {
tree[rt] = g[id[l]];
return;
}
int mid = (l + r) >> 1;
build(ls(rt), l, mid);
build(rs(rt), mid + 1, r);
push_up(rt);
}
matrix ask(int rt, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
return tree[rt];
}
int mid = (l + r) >> 1;
if (qr <= mid) {
return ask(ls(rt), l, mid, ql, qr);
}
if (mid < ql) {
return ask(rs(rt), mid + 1, r, ql, qr);
}
return ask(ls(rt), l, mid, ql, qr) * ask(rs(rt), mid + 1, r, ql, qr);
}
inline void change(int rt, int l, int r, int pos) {
if (l == r) {
tree[rt] = g[id[l]];
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) {
change(ls(rt), l, mid, pos);
} else {
change(rs(rt), mid + 1, r, pos);
}
push_up(rt);
}
void update(int x, int val) {
g[x].g[1][0] += val - a[x];
a[x] = val;
while (x) {
matrix last = ask(1, 1, n, dfn[top[x]], ed[top[x]]);
change(1, 1, n, dfn[x]);
matrix now = ask(1, 1, n, dfn[top[x]], ed[top[x]]);
x = fa[top[x]];
g[x].g[0][0] += max(now.g[0][0], now.g[1][0]) - max(last.g[0][0], last.g[1][0]);
g[x].g[0][1] = g[x].g[0][0];
g[x].g[1][0] += now.g[0][0] - last.g[0][0];
}
}
void dfs1(int u) {
int weight = 0;
siz[u] = 1;
f[u][1] = a[u];
for (int i = head[u]; i != 0; i = nxt[i]) {
int v = to[i];
if (v == fa[u]) {
continue;
}
dep[v] = dep[u] + 1;
fa[v] = u;
dfs1(v);
siz[u] += siz[v];
if (siz[v] > weight) {
weight = siz[v];
son[u] = v;
}
f[u][1] += f[v][0];
f[u][0] += max(f[v][0], f[v][1]);
}
}
void dfs2(int u, int list_Top) {
top[u] = list_Top;
dfn[u] = ++idx;
id[idx] = u;
ed[list_Top] = idx;
g[u].g[1][0] = a[u];
g[u].g[1][1] = -inf;
if (!son[u]) {
return;
}
dfs2(son[u], list_Top);
for (int i = head[u]; i != 0; i = nxt[i]) {
int v = to[i];
if (v == fa[u] || v == son[u]) {
continue;
}
dfs2(v, v);
g[u].g[0][0] += max(f[v][0], f[v][1]);
g[u].g[1][0] += f[v][0];
}
g[u].g[0][1] = g[u].g[0][0];
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i < n; i++) {
int s, t;
cin >> s >> t;
add(s, t);
add(t, s);
}
dep[1] = 1;
dfs1(1);
dfs2(1, 1);
build(1, 1, n);
for (int i = 1; i <= m; i++) {
int x;
int val;
cin >> x >> val;
update(x, val);
matrix ans = ask(1, 1, n, 1, ed[1]);
cout << max(ans.g[0][0], ans.g[1][0]) << endl;
}
return 0;
}