#include <bits/stdc++.h>
using namespace std;

const int MAXN = 100000 + 10, inf = 1e9;

struct Node {
    int dis, label;
    Node() {}
    Node(int _d, int _l) : dis(_d), label(_l) {}
    bool operator < (const Node &rhs) const {
        return dis < rhs.dis || (dis == rhs.dis && label < rhs.label);
    }
};

struct Edge {
    int v, w, nxt;
    Edge() {}
    Edge(int _v, int _w, int _n) : v(_v), w(_w), nxt(_n) {}
} E[MAXN << 1];

Node Belong[MAXN];
int G[MAXN], vis[MAXN];
int mark[MAXN], ret[MAXN];
int N, sz;

namespace TreeSplit {
    int total, root, mins;
    int size[MAXN];
    void getroot(int u, int f) {
        size[u] = 1; int mx = 0;
        for (int now = G[u]; ~now; now = E[now].nxt) {
            int v = E[now].v; if (vis[v] || v == f) continue;
            getroot(v, u); size[u] += size[v];
            mx = max(mx, size[v]);
        }
        mx = max(mx, total - size[u]);
        if (mx < mins) mins = mx, root = u;
    }
    void getsize(int u, int f) {
        size[u] = 1;
        for (int now = G[u]; ~now; now = E[now].nxt) {
            int v = E[now].v; if (vis[v] || v == f) continue;
            getsize(v, u); size[u] += size[v];
        }
    }
    vector<Node> dis, rest;
    void dfs(int u, int f, int d) {
        dis.push_back(Node(d, u));
        for (int now = G[u]; ~now; now = E[now].nxt) {
            int v = E[now].v, w = E[now].w; if (vis[v] || v == f) continue;
            dfs(v, u, d + w);
        }
    }
    void calc(int u, int f, int d, int sgn) {
        dis.clear(); rest.clear();
        dfs(u, f, d);
        for (int i = 0; i < (int)dis.size(); ++ i) {
            u = dis[i].label, d = dis[i].dis;
            rest.push_back(Node(Belong[u].dis - d, Belong[u].label));
        }
        sort(rest.begin(), rest.end());
        for (int i = 0; i < (int)dis.size(); ++ i) {
            u = dis[i].label, d = dis[i].dis;
            if (mark[u]) continue;
            int t = upper_bound(rest.begin(), rest.end(), dis[i]) - rest.begin();
            ret[u] += (rest.size() - t) * sgn;
        }
    }
    void work(int u, int sz) {
        total = sz; mins = inf;
        getroot(u, -1); u = root; vis[u] = true;
        calc(u, -1, 0, 1);
        for (int now = G[u]; ~now; now = E[now].nxt) {
            int v = E[now].v, w = E[now].w; if (vis[v]) continue;
            calc(v, u, w, -1);
        }
        getsize(u, -1);
        for (int now = G[u]; ~now; now = E[now].nxt) {
            int v = E[now].v; if (vis[v]) continue;
            work(v, size[v]);
        }
    }
}

void spfa() {
    queue<int> Q; 
    for (int i = 0; i < N; ++ i) {
        vis[i] = false; Belong[i] = Node(inf, -1);
        if (mark[i]) Q.push(i), Belong[i] = Node(0, i), vis[i] = true;
    }
    while (!Q.empty()) {
        int u = Q.front(); Q.pop(); vis[u] = false;
        for (int now = G[u]; ~now; now = E[now].nxt) {
            int v = E[now].v, w = E[now].w;
            Node tmp = Node(w + Belong[u].dis, Belong[u].label);
            if (tmp < Belong[v]) {
                Belong[v] = tmp;
                if (!vis[v]) vis[v] = true, Q.push(v);
            }
        }
    }
}

int main() {
    while (scanf("%d", &N) == 1) {
        for (int i = 0; i < N; ++ i) G[i] = -1; sz = 0;
        for (int i = 1; i < N; ++ i) {
            int u, v, w; scanf("%d%d%d", &u, &v, &w); -- u, -- v;
            E[sz] = Edge(v, w, G[u]); G[u] = sz ++;
            E[sz] = Edge(u, w, G[v]); G[v] = sz ++;
        }
        for (int i = 0; i < N; ++ i) scanf("%d", mark + i);
        spfa();
        for (int i = 0; i < N; ++ i) vis[i] = false;
        for (int i = 0; i < N; ++ i) ret[i] = 0;
        TreeSplit::work(0, N);
        int mx = 0;
        for (int i = 0; i < N; ++ i) mx = max(mx, ret[i]);
        printf("%d\n", mx);
    }
    return 0;
}
