#include <bits/stdc++.h>
typedef struct Node* ptr;
char _ibuf[(1 << 21 | 1)], _obuf[(1 << 21 | 1)], _stk[50];
char *ipos = _ibuf, *iend = _ibuf, *opos = _obuf, *oend = _obuf + (1 << 21 | 1),
     *stkpos = _stk;
struct END {
  ~END() { fwrite(_obuf, 1, opos - _obuf, stdout); }
} __;
inline int read() {
  register int x = 0, flag = 1;
  register char ch;
  while (!isdigit(
      ch = (ipos == iend and (iend = (ipos = _ibuf) +
                                     fread(_ibuf, 1, (1 << 21 | 1), stdin),
                              ipos == iend)
                ? EOF
                : *ipos++)))
    if (ch == '-') flag = -1;
  while (x = (x << 3) + (x << 1) + (ch & 15),
         isdigit(ch = (ipos == iend and
                               (iend = (ipos = _ibuf) +
                                       fread(_ibuf, 1, (1 << 21 | 1), stdin),
                                ipos == iend)
                           ? EOF
                           : *ipos++)))
    ;
  return x * flag;
}
template <typename _INT>
inline void write(_INT x) {
  if (x < 0)
    (opos == oend ? fwrite(_obuf, 1, (1 << 21 | 1), stdout), opos = _obuf : 0,
     *opos++ = ('-')),
        x = -x;
  while (*++stkpos = x % 10 ^ 48, x /= 10, x)
    ;
  while (stkpos != _stk)
    (opos == oend ? fwrite(_obuf, 1, (1 << 21 | 1), stdout), opos = _obuf : 0,
     *opos++ = (*stkpos--));
}
template <typename _Tp>
inline bool Chkmax(_Tp& x, const _Tp& y) {
  return x < y ? x = y, true : false;
}
template <typename _Tp>
inline bool Chkmin(_Tp& x, const _Tp& y) {
  return x > y ? x = y, true : false;
}
const int maxN = 4e5 + 2;
int n, m;
long long ans;
int col[maxN], fa[maxN];
long long delta[maxN << 1];
ptr root;
std::vector<int> G[maxN];
std::vector<std::pair<int, int> > modi[maxN];
struct Node {
  int size, virt;
  long long vir_2;
  ptr son[2], fa;
  Node() : size(1), virt(0), vir_2(0) { son[0] = son[1] = fa = nullptr; }
  int Ident() {
    return !this->fa                  ? -1
           : this->fa->son[0] == this ? 0
           : this->fa->son[1] == this ? 1
                                      : -1;
  }
  static int Size(ptr x) { return x ? x->size : 0; }
  void Pushup() {
    this->size = Size(this->son[0]) + Size(this->son[1]) + this->virt + 1;
  }
  void Rotate() {
    ptr curfa = this->fa;
    int dir = this->Ident();
    if (~curfa->Ident()) curfa->fa->son[curfa->Ident()] = this;
    if (this->son[dir ^ 1]) this->son[dir ^ 1]->fa = curfa;
    curfa->son[dir] = this->son[dir ^ 1], this->son[dir ^ 1] = curfa;
    this->fa = curfa->fa, curfa->fa = this;
    curfa->Pushup();
  }
  void Splay() {
    ptr curfa;
    while (~this->Ident()) {
      curfa = this->fa;
      if (~curfa->Ident())
        curfa->Ident() ^ this->Ident() ? this->Rotate() : curfa->Rotate();
      this->Rotate();
    }
    this->Pushup();
  }
};
inline void Access(ptr cur) {
  for (ptr son = nullptr; cur; son = cur, cur = cur->fa) {
    cur->Splay();
    (cur->virt += Node::Size(cur->son[1])) -= Node::Size(son);
    cur->vir_2 += (long long)Node::Size(cur->son[1]) * Node::Size(cur->son[1]);
    cur->vir_2 -= (long long)Node::Size(son) * Node::Size(son);
    cur->son[1] = son;
  }
}
inline ptr Findroot(ptr cur) {
  Access(cur), cur->Splay();
  while (cur->son[0]) cur = cur->son[0];
  cur->Splay();
  return cur;
}
inline void Link(int u) {
  ptr cur = root + u, curfa = root + fa[u];
  Access(cur), ans += cur->vir_2;
  ptr currt = Findroot(curfa);
  Access(currt), ans += currt->vir_2;
  Access(curfa), curfa->Splay();
  cur->fa = curfa;
  curfa->virt += cur->size;
  curfa->vir_2 += (long long)cur->size * cur->size;
  curfa->size += cur->size;
  Access(currt), ans -= currt->vir_2;
}
inline void Cut(int u) {
  ptr cur = root + u, curfa = root + fa[u], currt = Findroot(cur);
  Access(currt), ans += currt->vir_2;
  Access(curfa), curfa->Splay();
  curfa->virt -= cur->size;
  curfa->vir_2 -= (long long)cur->size * cur->size;
  curfa->size -= cur->size;
  cur->fa = nullptr;
  Access(cur), ans -= cur->vir_2;
  Access(currt), ans -= currt->vir_2;
}
void DFS(int u) {
  for (int v : G[u])
    if (v != fa[u]) fa[v] = u, DFS(v);
}
int main() {
  n = read(), m = read();
  root = new Node[n + 2];
  for (int i = 1; i <= n; ++i)
    modi[col[i] = read()].push_back(std::pair<int, int>(i, i));
  for (int i = 2; i <= n; ++i) {
    int u = read(), v = read();
    G[u].push_back(v), G[v].push_back(u);
  }
  fa[1] = n + 1, DFS(1);
  for (int i = 1; i <= n; ++i) Link(i);
  for (int i = 1; i <= m; ++i) {
    int u = read(), x = read();
    modi[col[u]].push_back(std::pair<int, int>(u, -i - n));
    modi[x].push_back(std::pair<int, int>(u, i + n));
    col[u] = x;
  }
  ans = 0;
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j < modi[i].size(); ++j) {
      int u = modi[i][j].first, t = modi[i][j].second;
      if (t < 0)
        Link(u);
      else
        Cut(u);
      if (j != modi[i].size() - 1)
        delta[std::abs(t)] += ans,
            delta[std::abs(modi[i][j + 1].second)] -= ans;
      else
        delta[std::abs(t)] += ans;
    }
    for (int j = modi[i].size() - 1; ~j; --j) {
      int u = modi[i][j].first, t = modi[i][j].second;
      if (t < 0)
        Cut(u);
      else
        Link(u);
    }
  }
  ans = 0;
  for (int i = 1; i <= n; ++i) ans += delta[i];
  write(ans), (opos == oend ? fwrite(_obuf, 1, (1 << 21 | 1), stdout),
               opos = _obuf : 0, *opos++ = ('\n'));
  for (int i = 1; i <= m; ++i)
    write(ans += delta[i + n]),
        (opos == oend ? fwrite(_obuf, 1, (1 << 21 | 1), stdout),
         opos = _obuf : 0, *opos++ = ('\n'));
  return 0;
}
