#include <bits/stdc++.h>
using namespace std;
namespace IO {
const int BUFFER_SIZE = 1 << 15;
char input_buffer[BUFFER_SIZE];
int input_pos = 0, input_len = 0;
char output_buffer[BUFFER_SIZE];
int output_pos = 0;
char number_buffer[100];
uint8_t lookup[100];
void _update_input_buffer() {
  input_len = fread(input_buffer, sizeof(char), BUFFER_SIZE, stdin);
  input_pos = 0;
  if (input_len == 0) input_buffer[0] = EOF;
}
inline char next_char(bool advance = true) {
  if (input_pos >= input_len) _update_input_buffer();
  return input_buffer[advance ? input_pos++ : input_pos];
}
inline bool isspace(char c) {
  return (unsigned char)(c - '\t') < 5 || c == ' ';
}
template <typename T>
inline void read_int(T& number) {
  bool negative = false;
  number = 0;
  while (!isdigit(next_char(false)))
    if (next_char() == '-') negative = true;
  do {
    number = 10 * number + (next_char() - '0');
  } while (isdigit(next_char(false)));
  if (negative) number = -number;
}
template <typename T, typename... Args>
inline void read_int(T& number, Args&... args) {
  read_int(number);
  read_int(args...);
}
inline void read_char(char& c) {
  while (isspace(next_char(false))) next_char();
  c = next_char();
}
inline void read_str(string& str) {
  while (isspace(next_char(false))) next_char();
  str.clear();
  do {
    str += next_char();
  } while (!isspace(next_char(false)));
}
void _flush_output() {
  fwrite(output_buffer, sizeof(char), output_pos, stdout);
  output_pos = 0;
}
inline void write_char(char c) {
  if (output_pos == BUFFER_SIZE) _flush_output();
  output_buffer[output_pos++] = c;
}
template <typename T>
inline void write_int(T number, char after = '\0') {
  if (number < 0) {
    write_char('-');
    number = -number;
  }
  int length = 0;
  while (number >= 10) {
    uint8_t lookup_value = lookup[number % 100];
    number /= 100;
    number_buffer[length++] = (lookup_value & 15) + '0';
    number_buffer[length++] = (lookup_value >> 4) + '0';
  }
  if (number != 0 || length == 0) write_char(number + '0');
  for (int i = length - 1; i >= 0; i--) write_char(number_buffer[i]);
  if (after) write_char(after);
}
inline void write_str(const string& str, char after = '\0') {
  for (char c : str) write_char(c);
  if (after) write_char(after);
}
void init() {
  bool exit_success = atexit(_flush_output) == 0;
  assert(exit_success);
  for (int i = 0; i < 100; i++) lookup[i] = (i / 10 << 4) + i % 10;
}
}  // namespace IO
template <class node>
struct link_cut_tree {
  bool connected(node* u, node* v) { return lca(u, v) != NULL; }
  int depth(node* u) {
    access(u);
    return get_sz(u->ch[0]);
  }
  node* get_root(node* u) {
    access(u);
    while (u->ch[0]) u = u->ch[0], u->push();
    return access(u), u;
  }
  node* ancestor(node* u, int k) {
    k = depth(u) - k;
    for (;; u->push()) {
      int sz = get_sz(u->ch[0]);
      if (sz == k) return access(u), u;
      if (sz < k)
        k -= sz + 1, u = u->ch[1];
      else
        u = u->ch[0];
    }
  }
  node* lca(node* u, node* v) {
    if (u == v) return u;
    access(u);
    access(v);
    if (!u->p) return NULL;
    u->splay();
    return u->p ?: u;
  }
  void link(node* u, node* v) {
    make_root(v);
    access(u);
    set_link(v, u, 0);
    v->update();
  }
  void cut(node* u) {
    access(u);
    u->ch[0]->p = NULL;
    u->ch[0] = NULL;
    u->update();
  }
  void cut(node* u, node* v) { cut(depth(u) > depth(v) ? u : v); }
  void make_root(node* u) {
    access(u);
    u->rev ^= 1;
    access(u);
  }
  void access(node* u) {
    for (node *v = u, *pre = NULL; v; v = v->p) {
      v->splay();
      if (pre) v->update_vsub(pre, false);
      if (v->ch[1]) v->update_vsub(v->ch[1], true);
      v->ch[1] = pre;
      v->update();
      pre = v;
    }
    u->splay();
  }
  node* operator[](int i) { return &data[i]; }
  int operator[](node* i) { return i - &data[0]; }
  vector<node> data;
  link_cut_tree(int n) : data(n) {}
};
template <typename pnode>
struct splay_tree {
  pnode ch[2], p;
  bool rev;
  int sz;
  splay_tree() {
    ch[0] = ch[1] = p = NULL;
    rev = 0;
    sz = 1;
  }
  friend int get_sz(pnode u) { return u ? u->sz : 0; }
  virtual void update() {
    if (ch[0]) ch[0]->push();
    if (ch[1]) ch[1]->push();
    sz = 1 + get_sz(ch[0]) + get_sz(ch[1]);
  }
  virtual void push() {
    if (rev) {
      if (ch[0]) ch[0]->rev ^= 1;
      if (ch[1]) ch[1]->rev ^= 1;
      swap(ch[0], ch[1]);
      rev = 0;
    }
  }
  int dir() {
    if (!p) return -2;
    if (p->ch[0] == this) return 0;
    if (p->ch[1] == this) return 1;
    return -1;
  }
  bool is_root() { return dir() < 0; }
  friend void set_link(pnode u, pnode v, int d) {
    if (v) v->p = u;
    if (d >= 0) u->ch[d] = v;
  }
  void rotate() {
    int x = dir();
    pnode g = p;
    set_link(g->p, static_cast<pnode>(this), g->dir());
    set_link(g, ch[x ^ 1], x);
    set_link(static_cast<pnode>(this), g, x ^ 1);
    g->update();
    update();
  }
  void splay() {
    while (!is_root() && !p->is_root()) {
      p->p->push(), p->push(), push();
      dir() == p->dir() ? p->rotate() : rotate();
      rotate();
    }
    if (!is_root()) p->push(), push(), rotate();
    push();
  }
};
struct node : splay_tree<node*> {
  using splay_tree::ch;
  int rsz, vrsz;
  long long chsz2, vchsz2;
  node() : splay_tree() {
    rsz = 1;
    vrsz = chsz2 = vchsz2 = 0;
  }
  void update() override {
    splay_tree::update();
    rsz = 1 + (ch[0] ? ch[0]->rsz : 0) + (ch[1] ? ch[1]->rsz : 0) + vrsz;
    chsz2 = (ch[0] ? ((long long)ch[0]->rsz * ch[0]->rsz) : 0) +
            (ch[1] ? ((long long)ch[1]->rsz * ch[1]->rsz) : 0) + vchsz2;
  }
  void update_vsub(node* v, bool add) {
    vrsz += (add ? +1 : -1) * v->rsz;
    vchsz2 += (add ? +1 : -1) * (long long)v->rsz * v->rsz;
  }
  void push() override { splay_tree::push(); }
};
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0);
  IO::init();
  int n, q;
  IO::read_int(n, q);
  vector<int> col(n);
  vector<vector<pair<int, int>>> e(n);
  for (int i = 0, x; i < n; ++i) {
    IO::read_int(x);
    --x;
    e[x].push_back({0, i});
    col[i] = x;
  }
  vector<vector<int>> adj(n + 1);
  for (int i = 1, u, v; i < n; ++i) {
    IO::read_int(u, v);
    --u, --v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  adj[n].push_back(0);
  link_cut_tree<node> lct(n + 1);
  vector<int> parent(n + 1, -1);
  function<void(int)> dfs = [&](int u) {
    for (auto v : adj[u])
      if (v != parent[u]) {
        lct.link(lct[u], lct[v]);
        parent[v] = u;
        dfs(v);
      }
  };
  dfs(n);
  for (int i = 1, u, x; i <= q; ++i) {
    IO::read_int(u, x);
    --u, --x;
    if (col[u] == x) continue;
    e[col[u]].push_back({i, ~u});
    e[x].push_back({i, u});
    col[u] = x;
  }
  vector<long long> ans(q + 1);
  vector<bool> nodes(n);
  for (auto& c : e) {
    long long last = 0, sz2 = (long long)n * n;
    for (auto& i : c) {
      int ru = max(i.second, ~i.second);
      auto u = lct[ru], pu = lct[parent[ru]], r = lct.get_root(pu);
      if (i.second < 0) {
        nodes[ru] = false;
        sz2 -= r->chsz2;
        lct.access(u);
        sz2 -= u->chsz2;
        lct.link(pu, u);
        lct.access(r);
        sz2 += r->chsz2;
      } else {
        nodes[ru] = true;
        sz2 -= r->chsz2;
        lct.cut(u);
        sz2 += u->chsz2;
        lct.access(r);
        sz2 += r->chsz2;
      }
      if (i.first > 0 || &i == &c.back() || c[&i - &c[0] + 1].first > 0) {
        ans[i.first] += -last;
        ans[i.first] += (last = (long long)n * n - sz2);
      }
    }
    for (auto& i : c) {
      int ru = max(i.second, ~i.second);
      if (nodes[ru]) {
        nodes[ru] = false;
        lct.link(lct[parent[ru]], lct[ru]);
      }
    }
  }
  partial_sum(ans.begin(), ans.end(), ans.begin());
  for (auto& i : ans) cout << i << "\n";
  return 0;
}
