#include <bits/stdc++.h>
#define all(vec) vec.begin(), vec.end()
using namespace std;
using ll = long long;
using P = pair<int, int>;
constexpr ll INF = (1LL << 30) - 1LL;
constexpr ll LINF = (1LL << 60) - 1LL;
constexpr ll MOD = 1e9 + 7;
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chmax(T &a, T b) { a = max(a, b); }
int n, k;
vector<vector<int>> G;
struct UF {
    int n, val;
    vector<int> par, siz, cnt;
    unordered_map<int, int> mp;
    UF() {
        n = 0;
        val = 0;
    }
    void add(int v) {
        par.emplace_back(n);
        siz.emplace_back(1);
        cnt.emplace_back(0);
        mp[v] = n;
        ++n;
    }
    int find(int x) {
        if (par[x] == x) {
            return x;
        }
        return par[x] = find(par[x]);
    }
    void unite(int u, int v) {
        if (!mp.count(u)) {
            add(u);
        }
        if (!mp.count(v)) {
            add(v);
        }
        u = mp[u], v = mp[v];
        u = find(u), v = find(v);
        if (u == v) {
            if (cnt[u] == siz[u] - 1) {
                val++;
            }
            cnt[u]++;
            return;
        }
        if (siz[u] < siz[v]) {
            swap(u, v);
        }
        val -= min(cnt[u], siz[u]);
        val -= min(cnt[v], siz[v]);
        siz[u] += siz[v];
        cnt[u] += cnt[v] + 1;
        val += min(cnt[u], siz[u]);
        par[v] = u;
    }
};
UF uf[100000];
vector<P> es[100000];
int id[100000], res[100000];
int merge(int u, int v) {
    u = id[u], v = id[v];
    if (es[u].size() < es[v].size()) {
        swap(u, v);
    }
    for (auto &e : es[v]) {
        uf[u].unite(e.first, e.second);
        es[u].emplace_back(e);
    }
    return u;
}
void dfs(int i, int p) {
    uf[i].unite(es[i][0].first, es[i][0].second);
    id[i] = i;
    int b = i;
    for (auto &e : G[i]) {
        if (e == p) {
            continue;
        }
        dfs(e, i);
        b = merge(b, id[e]);
    }
    res[i] = uf[b].val;
    id[i] = b;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> k;
    G.resize(n);
    for (int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        --a;
        --b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    for (int i = 0; i < n; i++) {
        int c, d;
        cin >> c >> d;
        --c;
        --d;
        es[i].emplace_back(P(c, d));
    }
    dfs(0, -1);
    for (int i = 0; i < n; i++) {
        cout << res[i] << endl;
    }
}

### Prompt

Please create a solution in cpp to the following problem:

H: Colorful Tree

Story

Yamiuchi (assassination) is a traditional event that is held annually in JAG summer camp. Every team displays a decorated tree in the dark and all teams' trees are compared from the point of view of their colorfulness. In this competition, it is allowed to cut the other teams’ tree to reduce its colorfulness. Despite a team would get a penalty if it were discovered that the team cuts the tree of another team, many teams do this obstruction.

You decided to compete in Yamiuchi and write a program that maximizes the colorfulness of your team’s tree. The program has to calculate maximum scores for all subtrees in case the other teams cut your tree.

Problem Statement

You are given a rooted tree G with N vertices indexed with 1 through N. The root is vertex 1. There are K kinds of colors indexed with 1 through K. You can paint vertex i with either color c_i or d_i. Note that c_i = d_i may hold, and if so you have to paint vertex i with c_i (=d_i).

Let the colorfulness of tree T be the number of different colors in T. Your task is to write a program that calculates maximum colorfulness for all rooted subtrees. Note that coloring for each rooted subtree is done independently, so previous coloring does not affect to other coloring.

Input


N K
u_1 v_1
:
u_{N-1} v_{N-1}
c_1 d_1
:
c_N d_N


The first line contains two integers N and K in this order.

The following N-1 lines provide information about the edges of G. The i-th line of them contains two integers u_i and v_i, meaning these two vertices are connected with an edge.

The following N lines provide information about color constraints. The i-th line of them contains two integers c_i and d_i explained above.

Constraints

* 1 \leq N \leq 10^5
* 1 \leq K \leq 2\times 10^5
* 1 \leq u_i , v_i \leq N
* 1 \leq c_i , d_i \leq K
* The input graph is a tree.
* All inputs are integers.



Output

Output N lines.

The i-th line of them contains the maximum colorfulness of the rooted subtree of G whose root is i.

Sample Input 1


2 10
1 2
1 9
8 7


Output for Sample Input 1


2
1


Sample Input 2


3 2
1 2
1 3
1 2
1 1
1 2


Output for Sample Input 2


2
1
1


Note that two color options of a vertex can be the same.

Sample Input 3


5 100000
4 3
3 5
1 3
2 1
3 2
1 3
2 1
4 2
1 4


Output for Sample Input 3


4
1
3
1
1






Example

Input

2 10
1 2
1 9
8 7


Output

2
1

### Response

```cpp
#include <bits/stdc++.h>
#define all(vec) vec.begin(), vec.end()
using namespace std;
using ll = long long;
using P = pair<int, int>;
constexpr ll INF = (1LL << 30) - 1LL;
constexpr ll LINF = (1LL << 60) - 1LL;
constexpr ll MOD = 1e9 + 7;
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chmax(T &a, T b) { a = max(a, b); }
int n, k;
vector<vector<int>> G;
struct UF {
    int n, val;
    vector<int> par, siz, cnt;
    unordered_map<int, int> mp;
    UF() {
        n = 0;
        val = 0;
    }
    void add(int v) {
        par.emplace_back(n);
        siz.emplace_back(1);
        cnt.emplace_back(0);
        mp[v] = n;
        ++n;
    }
    int find(int x) {
        if (par[x] == x) {
            return x;
        }
        return par[x] = find(par[x]);
    }
    void unite(int u, int v) {
        if (!mp.count(u)) {
            add(u);
        }
        if (!mp.count(v)) {
            add(v);
        }
        u = mp[u], v = mp[v];
        u = find(u), v = find(v);
        if (u == v) {
            if (cnt[u] == siz[u] - 1) {
                val++;
            }
            cnt[u]++;
            return;
        }
        if (siz[u] < siz[v]) {
            swap(u, v);
        }
        val -= min(cnt[u], siz[u]);
        val -= min(cnt[v], siz[v]);
        siz[u] += siz[v];
        cnt[u] += cnt[v] + 1;
        val += min(cnt[u], siz[u]);
        par[v] = u;
    }
};
UF uf[100000];
vector<P> es[100000];
int id[100000], res[100000];
int merge(int u, int v) {
    u = id[u], v = id[v];
    if (es[u].size() < es[v].size()) {
        swap(u, v);
    }
    for (auto &e : es[v]) {
        uf[u].unite(e.first, e.second);
        es[u].emplace_back(e);
    }
    return u;
}
void dfs(int i, int p) {
    uf[i].unite(es[i][0].first, es[i][0].second);
    id[i] = i;
    int b = i;
    for (auto &e : G[i]) {
        if (e == p) {
            continue;
        }
        dfs(e, i);
        b = merge(b, id[e]);
    }
    res[i] = uf[b].val;
    id[i] = b;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> k;
    G.resize(n);
    for (int i = 0; i < n - 1; i++) {
        int a, b;
        cin >> a >> b;
        --a;
        --b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    for (int i = 0; i < n; i++) {
        int c, d;
        cin >> c >> d;
        --c;
        --d;
        es[i].emplace_back(P(c, d));
    }
    dfs(0, -1);
    for (int i = 0; i < n; i++) {
        cout << res[i] << endl;
    }
}

```