#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void chkmax(T &x, T y) {
  x = max(x, y);
}
template <typename T>
inline void chkmin(T &x, T y) {
  x = min(x, y);
}
template <typename T>
inline void read(T &x) {
  T f = 1;
  x = 0;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -f;
  for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
  x *= f;
}
const int N = 4e5 + 10;
namespace Link_Cut_Tree {
long long now;
struct Node {
  int fa, ch[2], sz, vsz;
  long long ssz;
  long long Val() { return (long long)sz * sz; }
} T[N];
inline bool isroot(int x) {
  return T[T[x].fa].ch[0] != x && T[T[x].fa].ch[1] != x;
}
inline void pushup(int x) {
  T[x].sz = T[(T[x].ch[0])].sz + T[(T[x].ch[1])].sz + T[x].vsz + 1;
}
inline void rotate(int x) {
  int y = T[x].fa, z = T[y].fa, k = T[y].ch[1] == x;
  if (!isroot(y)) T[z].ch[T[z].ch[1] == y] = x;
  T[x].fa = z;
  T[y].ch[k] = T[x].ch[k ^ 1];
  T[T[x].ch[k ^ 1]].fa = y;
  T[x].ch[k ^ 1] = y;
  T[y].fa = x;
  pushup(y);
  pushup(x);
}
inline void splay(int x) {
  while (!isroot(x)) {
    int y = T[x].fa, z = T[y].fa;
    if (!isroot(y))
      (T[y].ch[0] == x) ^ (T[z].ch[0] == y) ? rotate(x) : rotate(y);
    rotate(x);
  }
}
inline void access(int x) {
  for (int y = 0; x; y = x, x = T[x].fa) {
    splay(x);
    T[x].vsz -= T[y].sz;
    T[x].vsz += T[(T[x].ch[1])].sz;
    T[x].ssz -= T[y].Val();
    T[x].ssz += T[(T[x].ch[1])].Val();
    (T[x].ch[1]) = y;
    pushup(x);
  }
}
inline int findroot(int x) {
  access(x);
  splay(x);
  while ((T[x].ch[0])) x = (T[x].ch[0]);
  splay(x);
  return x;
}
inline void link(int x, int y) {
  splay(x);
  now -= T[x].ssz + T[(T[x].ch[1])].Val();
  int z = findroot(y);
  access(x);
  splay(z);
  now -= T[T[z].ch[1]].Val();
  T[x].fa = y;
  splay(y);
  T[y].vsz += T[x].sz;
  T[y].ssz += T[x].Val();
  pushup(y);
  access(x);
  splay(z);
  now += T[T[z].ch[1]].Val();
  return;
}
inline void cut(int x, int y) {
  access(x);
  now += T[x].ssz;
  int z = findroot(y);
  access(x);
  splay(z);
  now -= T[T[z].ch[1]].Val();
  splay(x);
  T[x].ch[0] = T[T[x].ch[0]].fa = 0;
  pushup(x);
  splay(z);
  now += T[T[z].ch[1]].Val();
  return;
}
}  // namespace Link_Cut_Tree
using namespace Link_Cut_Tree;
int n, m;
int c[N], col[N], up[N];
long long ans[N];
vector<int> E[N];
vector<pair<int, int> > V[N];
inline void DFS(int u, int par) {
  up[u] = par;
  for (auto v : E[u]) {
    if (v == par) continue;
    DFS(v, u);
  }
}
int main() {
  read(n);
  read(m);
  for (int i = 1; i <= n; ++i) read(c[i]);
  for (int i = 1; i < n; ++i) {
    int u, v;
    read(u), read(v);
    E[u].push_back(v);
    E[v].push_back(u);
  }
  for (int i = 1; i <= n; ++i) V[c[i]].push_back(make_pair(0, i));
  for (int i = 1; i <= m; ++i) {
    int u, v;
    read(u), read(v);
    V[c[u]].push_back(make_pair(i, u));
    c[u] = v;
    V[c[u]].push_back(make_pair(i, u));
  }
  DFS(1, n + 1);
  for (int i = 1; i <= n + 1; ++i) pushup(i);
  for (int i = 1; i <= n; ++i) link(i, up[i]);
  for (int i = 1; i <= n; ++i) {
    long long lst = 0LL;
    for (auto x : V[i]) {
      int u = x.second, pos = x.first;
      if (col[u])
        link(u, up[u]);
      else
        cut(u, up[u]);
      col[u] ^= 1;
      ans[pos] += (long long)n * n - lst - now;
      lst = (long long)n * n - now;
    }
    for (auto x : V[i]) {
      int u = x.second;
      if (col[u]) link(u, up[u]), col[u] ^= 1;
    }
  }
  for (int i = 1; i <= m; ++i) ans[i] += ans[i - 1];
  for (int i = 0; i <= m; ++i) printf("%lld\n", ans[i]);
  return 0;
}
