/**
 * Created by Aminul on 5/16/2019.
 */

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D_2_test {
    static boolean vis[], mark[];
    static int g[][][];
    static long count[][], ans[][];

    public static void main(String[] args) throws Exception {
        FastReader in = new FastReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);

        int n = in.nextInt();
        count = new long[2][2];
        ans = new long[2][2];
        int from[] = new int[n - 1], to[] = new int[n - 1], w[] = new int[n - 1];
        for (int i = 0; i < n - 1; i++) {
            int u = in.nextInt(), v = in.nextInt(), c = in.nextInt();
            from[i] = u;
            to[i] = v;
            w[i] = c;
        }
        int ug[][] = packU(n + 1, from, to);
        g = packWU(n + 1, from, to, w);
        //int centroids[] = new Centroid_Decomposition(ug, 1).centroids;
        buildCentroidTree(ug, 0);
        int centroids[] = ord;
        vis = new boolean[n + 1];
        mark = new boolean[n + 1];
        for (int u : centroids) {
            mark[u] = true;
            vis[u] = true;
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], +1);
            }
            ans[0][0] += count[0][0];
            ans[0][1] += count[0][1];
            ans[1][1] += count[1][1];
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], -1);
                calc(v[0], v[1], v[1]);
                dfs(v[0], v[1], v[1], +1);
            }
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], -1);
            }
            vis[u] = false;
        }

        long res = ans[0][0] + ans[0][1] + ans[1][1];
        pw.println(res);

        pw.close();
    }

    static void dfs(int u, int start, int curr, int val) {
        vis[u] = true;
        count[start][curr] += val;
        if (mark[u]) {
            vis[u] = false;
            return;
        }
        for (int v[] : g[u]) {
            int node = v[0], w = v[1];
            if (curr == 1 && w == 0) continue;
            if (vis[node]) continue;
            if (mark[node]) {
                count[start][curr | w] += val;
                continue;
            }
            dfs(node, start, curr | w, val);
        }
        vis[u] = false;
    }

    static void calc(int u, int start, int curr) {
        if (mark[u]) return;
        vis[u] = true;
        if (curr == 0) {
            if (start == 0) {
                ans[0][0] += count[0][0];
                ans[0][1] += count[0][1];
                ans[0][1] += count[1][1];
            } else {
                ans[0][1] += count[1][1];
            }
        } else {
            ans[1][1] += count[1][1];
        }

        for (int v[] : g[u]) {
            int node = v[0], w = v[1];
            if (mark[node] || vis[node]) continue;
            if (curr == 0 && w == 1) continue;
            calc(node, start, curr & w);
        }
        vis[u] = false;
    }

    public static int[][][] packWU(int n, int[] from, int[] to, int[] w) {
        int[][][] g = new int[n][][];
        int[] p = new int[n];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 0; i < n; i++)
            g[i] = new int[p[i]][2];
        for (int i = 0; i < from.length; i++) {
            --p[from[i]];
            g[from[i]][p[from[i]]][0] = to[i];
            g[from[i]][p[from[i]]][1] = w[i];
            --p[to[i]];
            g[to[i]][p[to[i]]][0] = from[i];
            g[to[i]][p[to[i]]][1] = w[i];
        }
        return g;
    }

    static int[][] packU(int n, int[] from, int[] to) {
        int[][] g = new int[n][];
        int[] p = new int[n];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 0; i < n; i++)
            g[i] = new int[p[i]];
        for (int i = 0; i < from.length; i++) {
            g[from[i]][--p[from[i]]] = to[i];
            g[to[i]][--p[to[i]]] = from[i];
        }
        return g;
    }

    static void debug(Object... obj) {
        System.err.println(Arrays.deepToString(obj));
    }
    static int ord[];
    public static int[] buildCentroidTree(int[][] g, int root) {
        int n = g.length;
        int[] ctpar = new int[n];
        Arrays.fill(ctpar, -1);
        ord = new int[n];
        buildCentroidTree(g, 0, new boolean[n], new int[n], ord, new int[n], ctpar);
        return ctpar;
    }

    private static int buildCentroidTree(int[][] g, int root, boolean[] sed, int[] par, int[] ord, int[] des, int[] ctpar)
    {
        // parent and level-order
        ord[0] = root;
        par[root] = -1;
        int r = 1;
        for(int p = 0;p < r;p++) {
            int cur = ord[p];
            for(int nex : g[cur]){
                if(par[cur] != nex && !sed[nex]){
                    ord[r++] = nex;
                    par[nex] = cur;
                }
            }
        }
        // if(r == 1)return;

        // DP and find a separator
        int sep = -1; // always exists
        outer:
        for(int i = r-1;i >= 0;i--){
            int cur = ord[i];
            des[cur] = 1;
            for(int e : g[cur]){
                if(par[cur] != e && !sed[e])des[cur] += des[e];
            }
            if(r-des[cur] <= r/2){
                for(int e : g[cur]){
                    if(par[cur] != e && !sed[e] && des[e] >= r/2+1)continue outer;
                }
                sep = cur;
                break;
            }
        }

        sed[sep] = true;
        for(int e : g[sep]){
            if(!sed[e])ctpar[buildCentroidTree(g, e, sed, par, ord, des, ctpar)] = sep;
        }
        return sep;
    }

    static class Centroid_Decomposition {
        int g[][];
        int[] size, par, centroids;
        int idx = 0;
        boolean[] vis;

        Centroid_Decomposition(int g[][], int root) { // 1-based indexed, root = 1
            this.g = g;
            int n = g.length;
            size = new int[n];
            par = new int[n];
            centroids = new int[n];
            idx = 0;
            vis = new boolean[n];
            calcSize(root, 0);
            decompose(root, 0);
        }

        int calcSize(int u, int p) {
            size[u] = 1;
            for (int v : g[u]) {
                if (v != p) {
                    size[u] += calcSize(v, u);
                }
            }
            return size[u];
        }

        void decompose(int u, int p) {
            int max = 0, v = -1;
            for (int x : g[u]) {
                if (!vis[x] && size[x] > max) {
                    max = size[x];
                    v = x;
                }
            }
            while (max > size[u] / 2) {
                int t = size[v];
                size[v] = size[u];
                size[u] = size[v] - t;
                u = v;
                max = 0;
                for (int x : g[u]) {
                    if (!vis[x] && size[x] > max) {
                        max = size[x];
                        v = x;
                    }
                }
            }
            par[u] = p;
            vis[u] = true;
            centroids[idx++] = u;
            for (int x : g[u]) {
                if (!vis[x]) {
                    decompose(x, u);
                }
            }
        }
    }

    static class FastReader {
        InputStream is;
        private byte[] inbuf = new byte[1024];
        private int lenbuf = 0, ptrbuf = 0;

        public FastReader(InputStream is) {
            this.is = is;
        }

        public int readByte() {
            if (lenbuf == -1) throw new InputMismatchException();
            if (ptrbuf >= lenbuf) {
                ptrbuf = 0;
                try {
                    lenbuf = is.read(inbuf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (lenbuf <= 0) return -1;
            }
            return inbuf[ptrbuf++];
        }

        public boolean isSpaceChar(int c) {
            return !(c >= 33 && c <= 126);
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

        public int skip() {
            int b;
            while ((b = readByte()) != -1 && isSpaceChar(b)) ;
            return b;
        }

        public String next() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while (!(isSpaceChar(b))) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public String nextLine() {
            int c = skip();
            StringBuilder sb = new StringBuilder();
            while (!isEndOfLine(c)) {
                sb.appendCodePoint(c);
                c = readByte();
            }
            return sb.toString();
        }

        public int nextInt() {
            int num = 0, b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }
            while (true) {
                if (b >= '0' && b <= '9') {
                    num = (num << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long nextLong() {
            long num = 0;
            int b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = (num << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public char[] next(int n) {
            char[] buf = new char[n];
            int b = skip(), p = 0;
            while (p < n && !(isSpaceChar(b))) {
                buf[p++] = (char) b;
                b = readByte();
            }
            return n == p ? buf : Arrays.copyOf(buf, p);
        }

        public char readChar() {
            return (char) skip();
        }
    }
}


/**
 * Created by Aminul on 5/16/2019.
 */

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D {
    static boolean vis[], mark[];
    static int g[][][];
    static int count[][] = new int[2][2], ans[][] = new int[2][2];

    public static void main(String[] args) throws Exception {
        FastReader in = new FastReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);

        int n = in.nextInt();
        int from[] = new int[n - 1], to[] = new int[n - 1], w[] = new int[n - 1];
        for (int i = 0; i < n - 1; i++) {
            int u = in.nextInt(), v = in.nextInt(), c = in.nextInt();
            from[i] = u;
            to[i] = v;
            w[i] = c;
        }
        int ug[][] = packU(n + 1, from, to);
        g = packWU(n + 1, from, to, w);
        int centroids[] = new Centroid_Decomposition(ug, 1).centroids;
        vis = new boolean[n + 1];
        mark = new boolean[n + 1];
        for (int u : centroids) {
            mark[u] = true;
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], +1);
            }
            ans[0][0] += count[0][0];
            ans[0][1] += count[0][1];
            ans[1][1] += count[1][1];
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], -1);
                calc(v[0], v[1], v[1]);
                dfs(v[0], v[1], v[1], +1);
            }
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], -1);
            }
            //debug(u, ans[0][0], ans[0][1], ans[1][1]);
        }

        long res = ans[0][1] + (ans[0][0]) + (ans[1][1]);
        pw.println(res);

        pw.close();
    }

    static void dfs(int u, int start, int curr, int val) {
        vis[u] = true;
        count[start][curr] += val;
        if (mark[u]) {
            vis[u] = false;
            return;
        }
        for (int v[] : g[u]) {
            int node = v[0], w = v[1];
            if (mark[node] || vis[node]) continue;
            if (curr == 1 && w == 0) continue;
            dfs(node, start, curr | w, val);
        }
        vis[u] = false;
    }

    static void calc(int u, int start, int curr) {
        if (mark[u]) return;
        vis[u] = true;
        if (curr == 0) {
            if (start == 0) {
                ans[0][0] += count[0][0];
                ans[0][0] += count[0][1];
            }
            ans[0][1] += count[1][1];
        } else {
            ans[1][1] += count[1][1];
        }

        for (int v[] : g[u]) {
            int node = v[0], w = v[1];
            if (mark[node] || vis[node]) continue;
            if (curr == 0 && w == 1) continue;
            calc(node, start, curr & w);
        }
        vis[u] = false;
    }

    public static int[][][] packWU(int n, int[] from, int[] to, int[] w) {
        int[][][] g = new int[n][][];
        int[] p = new int[n];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 0; i < n; i++)
            g[i] = new int[p[i]][2];
        for (int i = 0; i < from.length; i++) {
            --p[from[i]];
            g[from[i]][p[from[i]]][0] = to[i];
            g[from[i]][p[from[i]]][1] = w[i];
            --p[to[i]];
            g[to[i]][p[to[i]]][0] = from[i];
            g[to[i]][p[to[i]]][1] = w[i];
        }
        return g;
    }

    static int[][] packU(int n, int[] from, int[] to) {
        int[][] g = new int[n][];
        int[] p = new int[n];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 0; i < n; i++)
            g[i] = new int[p[i]];
        for (int i = 0; i < from.length; i++) {
            g[from[i]][--p[from[i]]] = to[i];
            g[to[i]][--p[to[i]]] = from[i];
        }
        return g;
    }

    static void debug(Object... obj) {
        System.err.println(Arrays.deepToString(obj));
    }

    static class Centroid_Decomposition {
        int g[][];
        int[] size, par;
        boolean[] vis;
        int centroids[], cd;

        Centroid_Decomposition(int g[][], int root) { // 1-based indexed, root = 1
            this.g = g;
            int n = g.length;
            size = new int[n];
            par = new int[n];
            vis = new boolean[n];
            centroids = new int[n - 1];
            cd = 0;
            calcSize(root, 0);
            decompose(root, 0);
        }

        int calcSize(int u, int p) {
            size[u] = 1;
            for (int v : g[u]) {
                if (v != p) {
                    size[u] += calcSize(v, u);
                }
            }
            return size[u];
        }

        void decompose(int u, int p) {
            int max = 0, v = -1;
            for (int x : g[u]) {
                if (!vis[x] && size[x] > max) {
                    max = size[x];
                    v = x;
                }
            }
            while (max > size[u] / 2) {
                int t = size[v];
                size[v] = size[u];
                size[u] = size[v] - t;
                u = v;
                max = 0;
                for (int x : g[u]) {
                    if (!vis[x] && size[x] > max) {
                        max = size[x];
                        v = x;
                    }
                }
            }
            centroids[cd++] = u;
            par[u] = p;
            vis[u] = true;
            for (int x : g[u]) {
                if (!vis[x]) {
                    decompose(x, u);
                }
            }
        }

        void update(int u) {
            for (int v = u; v != 0; v = par[v]) {
                //int dist = lca.dist(u, v);
                //nearest[v] = min(nearest[v], dist);
                //do update
            }
        }

        int query(int u) {
            int min = Integer.MAX_VALUE;
            for (int v = u; v != 0; v = par[v]) {
                //int dist = lca.dist(u, v);
                //min = min(min, dist + nearest[v]);
                //do query
            }
            return min;
        }

    }

    static class FastReader {
        InputStream is;
        private byte[] inbuf = new byte[1024];
        private int lenbuf = 0, ptrbuf = 0;

        public FastReader(InputStream is) {
            this.is = is;
        }

        public int readByte() {
            if (lenbuf == -1) throw new InputMismatchException();
            if (ptrbuf >= lenbuf) {
                ptrbuf = 0;
                try {
                    lenbuf = is.read(inbuf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (lenbuf <= 0) return -1;
            }
            return inbuf[ptrbuf++];
        }

        public boolean isSpaceChar(int c) {
            return !(c >= 33 && c <= 126);
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

        public int skip() {
            int b;
            while ((b = readByte()) != -1 && isSpaceChar(b)) ;
            return b;
        }

        public String next() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while (!(isSpaceChar(b))) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public String nextLine() {
            int c = skip();
            StringBuilder sb = new StringBuilder();
            while (!isEndOfLine(c)) {
                sb.appendCodePoint(c);
                c = readByte();
            }
            return sb.toString();
        }

        public int nextInt() {
            int num = 0, b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }
            while (true) {
                if (b >= '0' && b <= '9') {
                    num = (num << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long nextLong() {
            long num = 0;
            int b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = (num << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public char[] next(int n) {
            char[] buf = new char[n];
            int b = skip(), p = 0;
            while (p < n && !(isSpaceChar(b))) {
                buf[p++] = (char) b;
                b = readByte();
            }
            return n == p ? buf : Arrays.copyOf(buf, p);
        }

        public char readChar() {
            return (char) skip();
        }
    }
}


/**
 * Created by Aminul on 5/16/2019.
 */

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D_2 {
    static boolean vis[], mark[];
    static int g[][][];
    static long count[][], ans[][];

    public static void main(String[] args) throws Exception {
        FastReader in = new FastReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);

        int n = in.nextInt();
        count = new long[2][2];
        ans = new long[2][2];
        int from[] = new int[n - 1], to[] = new int[n - 1], w[] = new int[n - 1];
        for (int i = 0; i < n - 1; i++) {
            int u = in.nextInt(), v = in.nextInt(), c = in.nextInt();
            from[i] = u;
            to[i] = v;
            w[i] = c;
        }
        int ug[][] = packU(n + 1, from, to);
        g = packWU(n + 1, from, to, w);
        int centroids[] = new Centroid_Decomposition(ug, 1).centroids;
        vis = new boolean[n + 1];
        mark = new boolean[n + 1];
        for (int u : centroids) {
            mark[u] = true;
            vis[u] = true;
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], +1);
            }
            ans[0][0] += count[0][0];
            ans[0][1] += count[0][1];
            ans[1][1] += count[1][1];
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], -1);
                calc(v[0], v[1], v[1]);
                dfs(v[0], v[1], v[1], +1);
            }
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], -1);
            }
            vis[u] = false;
        }

        long res = ans[0][0] + ans[0][1] + ans[1][1];
        pw.println(res);

        pw.close();
    }

    static void dfs(int u, int start, int curr, int val) {
        vis[u] = true;
        count[start][curr] += val;
        if (mark[u]) {
            vis[u] = false;
            return;
        }
        for (int v[] : g[u]) {
            int node = v[0], w = v[1];
            if (curr == 1 && w == 0) continue;
            if (vis[node]) continue;
            if (mark[node]) {
                count[start][curr | w] += val;
                continue;
            }
            dfs(node, start, curr | w, val);
        }
        vis[u] = false;
    }

    static void calc(int u, int start, int curr) {
        if (mark[u]) return;
        vis[u] = true;
        if (curr == 0) {
            if (start == 0) {
                ans[0][0] += count[0][0];
                ans[0][1] += count[0][1];
                ans[0][1] += count[1][1];
            } else {
                ans[0][1] += count[1][1];
            }
        } else {
            ans[1][1] += count[1][1];
        }

        for (int v[] : g[u]) {
            int node = v[0], w = v[1];
            if (mark[node] || vis[node]) continue;
            if (curr == 0 && w == 1) continue;
            calc(node, start, curr & w);
        }
        vis[u] = false;
    }

    public static int[][][] packWU(int n, int[] from, int[] to, int[] w) {
        int[][][] g = new int[n][][];
        int[] p = new int[n];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 0; i < n; i++)
            g[i] = new int[p[i]][2];
        for (int i = 0; i < from.length; i++) {
            --p[from[i]];
            g[from[i]][p[from[i]]][0] = to[i];
            g[from[i]][p[from[i]]][1] = w[i];
            --p[to[i]];
            g[to[i]][p[to[i]]][0] = from[i];
            g[to[i]][p[to[i]]][1] = w[i];
        }
        return g;
    }

    static int[][] packU(int n, int[] from, int[] to) {
        int[][] g = new int[n][];
        int[] p = new int[n];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 0; i < n; i++)
            g[i] = new int[p[i]];
        for (int i = 0; i < from.length; i++) {
            g[from[i]][--p[from[i]]] = to[i];
            g[to[i]][--p[to[i]]] = from[i];
        }
        return g;
    }

    static void debug(Object... obj) {
        System.err.println(Arrays.deepToString(obj));
    }

    static class Centroid_Decomposition {
        int g[][];
        int[] size, par;
        boolean[] vis;
        int centroids[], cd;

        Centroid_Decomposition(int g[][], int root) { // 1-based indexed, root = 1
            this.g = g;
            int n = g.length;
            size = new int[n];
            par = new int[n];
            vis = new boolean[n];
            centroids = new int[n - 1];
            cd = 0;
            calcSize(root, 0);
            decompose(root, 0);
        }

        int calcSize(int u, int p) {
            size[u] = 1;
            for (int v : g[u]) {
                if (v != p) {
                    size[u] += calcSize(v, u);
                }
            }
            return size[u];
        }

        void decompose(int u, int p) {
            int max = 0, v = -1;
            for (int x : g[u]) {
                if (!vis[x] && size[x] > max) {
                    max = size[x];
                    v = x;
                }
            }
            while (max > size[u] / 2) {
                int t = size[v];
                size[v] = size[u];
                size[u] = size[v] - t;
                u = v;
                max = 0;
                for (int x : g[u]) {
                    if (!vis[x] && size[x] > max) {
                        max = size[x];
                        v = x;
                    }
                }
            }
            centroids[cd++] = u;
            par[u] = p;
            vis[u] = true;
            for (int x : g[u]) {
                if (!vis[x]) {
                    decompose(x, u);
                }
            }
        }

        void update(int u) {
            for (int v = u; v != 0; v = par[v]) {
                //int dist = lca.dist(u, v);
                //nearest[v] = min(nearest[v], dist);
                //do update
            }
        }

        int query(int u) {
            int min = Integer.MAX_VALUE;
            for (int v = u; v != 0; v = par[v]) {
                //int dist = lca.dist(u, v);
                //min = min(min, dist + nearest[v]);
                //do query
            }
            return min;
        }

    }

    static class FastReader {
        InputStream is;
        private byte[] inbuf = new byte[1024];
        private int lenbuf = 0, ptrbuf = 0;

        public FastReader(InputStream is) {
            this.is = is;
        }

        public int readByte() {
            if (lenbuf == -1) throw new InputMismatchException();
            if (ptrbuf >= lenbuf) {
                ptrbuf = 0;
                try {
                    lenbuf = is.read(inbuf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (lenbuf <= 0) return -1;
            }
            return inbuf[ptrbuf++];
        }

        public boolean isSpaceChar(int c) {
            return !(c >= 33 && c <= 126);
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

        public int skip() {
            int b;
            while ((b = readByte()) != -1 && isSpaceChar(b)) ;
            return b;
        }

        public String next() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while (!(isSpaceChar(b))) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public String nextLine() {
            int c = skip();
            StringBuilder sb = new StringBuilder();
            while (!isEndOfLine(c)) {
                sb.appendCodePoint(c);
                c = readByte();
            }
            return sb.toString();
        }

        public int nextInt() {
            int num = 0, b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }
            while (true) {
                if (b >= '0' && b <= '9') {
                    num = (num << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long nextLong() {
            long num = 0;
            int b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = (num << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public char[] next(int n) {
            char[] buf = new char[n];
            int b = skip(), p = 0;
            while (p < n && !(isSpaceChar(b))) {
                buf[p++] = (char) b;
                b = readByte();
            }
            return n == p ? buf : Arrays.copyOf(buf, p);
        }

        public char readChar() {
            return (char) skip();
        }
    }
}


/**
 * Created by Aminul on 5/16/2019.
 */

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D_2 {
    static boolean vis[], mark[];
    static int g[][][];
    static long count[][], ans[][];

    public static void main(String[] args) throws Exception {
        FastReader in = new FastReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);

        int n = in.nextInt();
        count = new long[2][2];
        ans = new long[2][2];
        int from[] = new int[n - 1], to[] = new int[n - 1], w[] = new int[n - 1];
        for (int i = 0; i < n - 1; i++) {
            int u = in.nextInt(), v = in.nextInt(), c = in.nextInt();
            from[i] = u;
            to[i] = v;
            w[i] = c;
        }
       // int ug[][] = packU(n + 1, from, to);
        g = packWU(n + 1, from, to, w);
        int centroids[] = new Centroid_Decomposition(g, 1).centroids;
        vis = new boolean[n + 1];
        mark = new boolean[n + 1];
        for (int u : centroids) {
            mark[u] = true;
            vis[u] = true;
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], +1);
            }
            ans[0][0] += count[0][0];
            ans[0][1] += count[0][1];
            ans[1][1] += count[1][1];
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], -1);
                calc(v[0], v[1], v[1]);
                dfs(v[0], v[1], v[1], +1);
            }
            for (int v[] : g[u]) {
                dfs(v[0], v[1], v[1], -1);
            }
            vis[u] = false;
        }

        long res = ans[0][0] + ans[0][1] + ans[1][1];
        pw.println(res);

        pw.close();
    }

    static void dfs(int u, int start, int curr, int val) {
        vis[u] = true;
        count[start][curr] += val;
        if (mark[u]) {
            vis[u] = false;
            return;
        }
        for (int v[] : g[u]) {
            int node = v[0], w = v[1];
            if (curr == 1 && w == 0) continue;
            if (vis[node]) continue;
            if (mark[node]) {
                count[start][curr | w] += val;
                continue;
            }
            dfs(node, start, curr | w, val);
        }
        vis[u] = false;
    }

    static void calc(int u, int start, int curr) {
        if (mark[u]) return;
        vis[u] = true;
        if (curr == 0) {
            if (start == 0) {
                ans[0][0] += count[0][0];
                ans[0][1] += count[0][1];
                ans[0][1] += count[1][1];
            } else {
                ans[0][1] += count[1][1];
            }
        } else {
            ans[1][1] += count[1][1];
        }

        for (int v[] : g[u]) {
            int node = v[0], w = v[1];
            if (mark[node] || vis[node]) continue;
            if (curr == 0 && w == 1) continue;
            calc(node, start, curr & w);
        }
        vis[u] = false;
    }

    public static int[][][] packWU(int n, int[] from, int[] to, int[] w) {
        int[][][] g = new int[n][][];
        int[] p = new int[n];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 0; i < n; i++)
            g[i] = new int[p[i]][2];
        for (int i = 0; i < from.length; i++) {
            --p[from[i]];
            g[from[i]][p[from[i]]][0] = to[i];
            g[from[i]][p[from[i]]][1] = w[i];
            --p[to[i]];
            g[to[i]][p[to[i]]][0] = from[i];
            g[to[i]][p[to[i]]][1] = w[i];
        }
        return g;
    }

    static int[][] packU(int n, int[] from, int[] to) {
        int[][] g = new int[n][];
        int[] p = new int[n];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 0; i < n; i++)
            g[i] = new int[p[i]];
        for (int i = 0; i < from.length; i++) {
            g[from[i]][--p[from[i]]] = to[i];
            g[to[i]][--p[to[i]]] = from[i];
        }
        return g;
    }

    static void debug(Object... obj) {
        System.err.println(Arrays.deepToString(obj));
    }

    static class Centroid_Decomposition {
        int g[][][];
        int[] size, par, centroids;
        int idx = 0;
        boolean[] vis;

        Centroid_Decomposition(int g[][][], int root) { // 1-based indexed, root = 1
            this.g = g;
            int n = g.length;
            size = new int[n];
            par = new int[n];
            centroids = new int[n];
            idx = 0;
            vis = new boolean[n];
            calcSize(root, 0);
            decompose(root, 0);
        }

        int calcSize(int u, int p) {
            size[u] = 1;
            for (int v[] : g[u]) {
                if (v[0] != p) {
                    size[u] += calcSize(v[0], u);
                }
            }
            return size[u];
        }

        void decompose(int u, int p) {
            int max = 0, v = -1;
            for (int e[] : g[u]) {
                int x = e[0];
                if (!vis[x] && size[x] > max) {
                    max = size[x];
                    v = x;
                }
            }
            while (max > (size[u] >> 1)) {
                int t = size[v];
                size[v] = size[u];
                size[u] = size[v] - t;
                u = v;
                max = 0;
                for (int e[] : g[u]) {
                    int x = e[0];
                    if (!vis[x] && size[x] > max) {
                        max = size[x];
                        v = x;
                    }
                }
            }
            par[u] = p;
            vis[u] = true;
            centroids[idx++] = u;
            for (int e[] : g[u]) {
                int x = e[0];
                if (!vis[x]) {
                    decompose(x, u);
                }
            }
        }
    }

    static class FastReader {
        InputStream is;
        private byte[] inbuf = new byte[1024];
        private int lenbuf = 0, ptrbuf = 0;

        public FastReader(InputStream is) {
            this.is = is;
        }

        public int readByte() {
            if (lenbuf == -1) throw new InputMismatchException();
            if (ptrbuf >= lenbuf) {
                ptrbuf = 0;
                try {
                    lenbuf = is.read(inbuf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (lenbuf <= 0) return -1;
            }
            return inbuf[ptrbuf++];
        }

        public boolean isSpaceChar(int c) {
            return !(c >= 33 && c <= 126);
        }

        private boolean isEndOfLine(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

        public int skip() {
            int b;
            while ((b = readByte()) != -1 && isSpaceChar(b)) ;
            return b;
        }

        public String next() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while (!(isSpaceChar(b))) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public String nextLine() {
            int c = skip();
            StringBuilder sb = new StringBuilder();
            while (!isEndOfLine(c)) {
                sb.appendCodePoint(c);
                c = readByte();
            }
            return sb.toString();
        }

        public int nextInt() {
            int num = 0, b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }
            while (true) {
                if (b >= '0' && b <= '9') {
                    num = (num << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long nextLong() {
            long num = 0;
            int b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = (num << 3) + (num << 1) + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public char[] next(int n) {
            char[] buf = new char[n];
            int b = skip(), p = 0;
            while (p < n && !(isSpaceChar(b))) {
                buf[p++] = (char) b;
                b = readByte();
            }
            return n == p ? buf : Arrays.copyOf(buf, p);
        }

        public char readChar() {
            return (char) skip();
        }
    }
}


import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        FastScanner sc = new FastScanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        int n = sc.nextInt();
        UnionFindTree uf0 = new UnionFindTree(n);
        UnionFindTree uf1 = new UnionFindTree(n);
        long ans = 0;
        for(int i = 0; i < n-1; i++){
            int x = sc.nextInt()-1;
            int y = sc.nextInt()-1;
            int e = sc.nextInt();
            if(e == 0){
                uf0.union(x,y);
            }else{
                uf1.union(x,y);
            }
        }
        for(int i = 0; i < n; i++){
            int find0 = uf0.find(i);
            int find1 = uf1.find(i);
            int tmp0 = uf0.size(find0);
            if(find0 == i){
                ans += (long)tmp0*(tmp0-1);
            }
            int tmp1 = uf1.size(find1);
            if(find1 == i){
                ans += (long)tmp1*(tmp1-1);
            }
            ans += (long)(tmp0-1)*(tmp1-1);
        }
        pw.println(ans);
        pw.close();
    }

    static class GeekInteger {
        public static void save_sort(int[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static int[] shuffle(int[] array) {
            int n = array.length;
            Random random = new Random();
            for (int i = 0, j; i < n; i++) {
                j = i + random.nextInt(n - i);
                int randomElement = array[j];
                array[j] = array[i];
                array[i] = randomElement;
            }
            return array;
        }
    }

}

class UnionFindTree {
	int[] parent;
	int[] size;

	public UnionFindTree(int size) {
		this.parent = new int[size];
		this.size = new int[size];
		for (int i = 0; i < size; i++) {
			makeSet(i);
		}
	}

	public void makeSet(int i) {
		parent[i] = i;
		size[i] = 1;
	}

	public void union(int x, int y) {
		int px = find(x);
		int py = find(y);
		if(px == py){
			return;
		}
		if(size[px] < size[py]){
			int tmp = px;
			px = py;
			py = tmp;
		}
		this.parent[py]=px;
        this.size[px]+=this.size[py];
        return;
	}

	public int find(int i) {
		if (i != parent[i]) {
			parent[i] = find(parent[i]);
		}
		return parent[i];
	}

	public boolean same(int x, int y) {
		return find(x) == find(y);
	}

	public int size(int x) {
		return size[find(x)];
	}

	public int nowSize(int x){
		return size[x];
	}
}

class FastScanner {
    private BufferedReader reader = null;
    private StringTokenizer tokenizer = null;
    public FastScanner(InputStream in) {
        reader = new BufferedReader(new InputStreamReader(in));
        tokenizer = null;
    }

    public String next() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public String nextLine() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                return reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken("\n");
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public double nextDouble() {
         return Double.parseDouble(next());
    }

    public String[] nextArray(int n) {
        String[] a = new String[n];
        for (int i = 0; i < n; i++)
            a[i] = next();
        return a;
    }

    public int[] nextIntArray(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++)
            a[i] = nextInt();
        return a;
    }

    public long[] nextLongArray(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++)
            a[i] = nextLong();
        return a;
    }
}


import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        FastScanner sc = new FastScanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        int n = sc.nextInt();
        UnionFindTree uf0 = new UnionFindTree(n);
        UnionFindTree uf1 = new UnionFindTree(n);
        int ans = 0;
        for(int i = 0; i < n-1; i++){
            int x = sc.nextInt()-1;
            int y = sc.nextInt()-1;
            int e = sc.nextInt();
            if(e == 0){
                uf0.union(x,y);
            }else{
                uf1.union(x,y);
            }
        }
        for(int i = 0; i < n; i++){
            int find0 = uf0.find(i);
            int find1 = uf1.find(i);
            int tmp0 = uf0.size(find0);
            if(find0 == i){
                ans += tmp0*(tmp0-1);
            }
            int tmp1 = uf1.size(find1);
            if(find1 == i){
                ans += tmp1*(tmp1-1);
            }
            ans += (tmp0-1)*(tmp1-1);
        }
        pw.println(ans);
        pw.close();
    }

    static class GeekInteger {
        public static void save_sort(int[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static int[] shuffle(int[] array) {
            int n = array.length;
            Random random = new Random();
            for (int i = 0, j; i < n; i++) {
                j = i + random.nextInt(n - i);
                int randomElement = array[j];
                array[j] = array[i];
                array[i] = randomElement;
            }
            return array;
        }
    }

}

class UnionFindTree {
	int[] parent;
	int[] size;

	public UnionFindTree(int size) {
		this.parent = new int[size];
		this.size = new int[size];
		for (int i = 0; i < size; i++) {
			makeSet(i);
		}
	}

	public void makeSet(int i) {
		parent[i] = i;
		size[i] = 1;
	}

	public void union(int x, int y) {
		int px = find(x);
		int py = find(y);
		if(px == py){
			return;
		}
		if(size[px] < size[py]){
			int tmp = px;
			px = py;
			py = tmp;
		}
		this.parent[py]=px;
        this.size[px]+=this.size[py];
        return;
	}

	public int find(int i) {
		if (i != parent[i]) {
			parent[i] = find(parent[i]);
		}
		return parent[i];
	}

	public boolean same(int x, int y) {
		return find(x) == find(y);
	}

	public int size(int x) {
		return size[find(x)];
	}

	public int nowSize(int x){
		return size[x];
	}
}

class FastScanner {
    private BufferedReader reader = null;
    private StringTokenizer tokenizer = null;
    public FastScanner(InputStream in) {
        reader = new BufferedReader(new InputStreamReader(in));
        tokenizer = null;
    }

    public String next() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public String nextLine() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                return reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken("\n");
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public double nextDouble() {
         return Double.parseDouble(next());
    }

    public String[] nextArray(int n) {
        String[] a = new String[n];
        for (int i = 0; i < n; i++)
            a[i] = next();
        return a;
    }

    public int[] nextIntArray(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++)
            a[i] = nextInt();
        return a;
    }

    public long[] nextLongArray(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++)
            a[i] = nextLong();
        return a;
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Washoum
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        inputClass in = new inputClass(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        D01Tree solver = new D01Tree();
        solver.solve(1, in, out);
        out.close();
    }

    static class D01Tree {
        static D01Tree.Node[] graph0;
        static D01Tree.Node[] graph1;
        static boolean[] visited0;
        static boolean[] visited1;
        static ArrayList<Integer> comp0;
        static ArrayList<Integer> comp1;
        static int size;

        public void solve(int testNumber, inputClass sc, PrintWriter out) {
            int n = sc.nextInt();
            int x, y, w;
            graph0 = new D01Tree.Node[n];
            graph1 = new D01Tree.Node[n];
            visited0 = new boolean[n];
            visited1 = new boolean[n];
            comp0 = new ArrayList<>();
            comp1 = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                graph0[i] = new D01Tree.Node();
                graph0[i].edges = new ArrayList<>();
                graph1[i] = new D01Tree.Node();
                graph1[i].edges = new ArrayList<>();
            }
            for (int i = 0; i < n - 1; i++) {
                x = sc.nextInt() - 1;
                y = sc.nextInt() - 1;
                w = sc.nextInt();
                if (w == 1) {
                    graph1[x].edges.add(y);
                    graph1[y].edges.add(x);
                } else if (w == 0) {
                    graph0[x].edges.add(y);
                    graph0[y].edges.add(x);
                }
            }

            for (int i = 0; i < n; i++) {
                if (!visited0[i]) {
                    size = 0;
                    dfs0(i, comp0.size());
                    comp0.add(size);
                }
            }
            for (int i = 0; i < n; i++) {
                if (!visited1[i]) {
                    size = 0;
                    dfs1(i, comp1.size());
                    comp1.add(size);
                }
            }

            long ans = 0;
            for (int i = 0; i < comp0.size(); i++) {
                ans += (long) comp0.get(i) * (long) (comp0.get(i) - 1);
            }
            for (int i = 0; i < comp1.size(); i++) {
                ans += (long) comp1.get(i) * (long) (comp1.get(i) - 1);
            }

            for (int i = 0; i < n; i++) {
                if (comp0.get(graph0[i].comp) > 1 && comp1.get(graph1[i].comp) > 1) {
                    ans += (long) (comp0.get(graph0[i].comp) - 1) * (long) (comp1.get(graph1[i].comp) - 1);
                }
            }
            out.println(ans);
        }

        private void dfs0(int a, int c) {
            visited0[a] = true;
            graph0[a].comp = c;
            size++;
            for (int i : graph0[a].edges) {
                if (!visited0[i])
                    dfs0(i, c);
            }
        }

        private void dfs1(int a, int c) {
            visited1[a] = true;
            graph1[a].comp = c;
            size++;
            for (int i : graph1[a].edges) {
                if (!visited1[i])
                    dfs1(i, c);
            }
        }

        static class Node {
            ArrayList<Integer> edges;
            int comp;

        }

    }

    static class inputClass {
        BufferedReader br;
        StringTokenizer st;

        public inputClass(InputStream in) {

            br = new BufferedReader(new InputStreamReader(in));
        }

        public String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.*; import java.util.*;
public class CF1156D {

    public static class Edge{
        int a, b;
        public Edge(int x, int y){
            this.a=x; this.b=y;
        }
    }
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        int N=Integer.parseInt(br.readLine());
        ArrayList<Edge> arl0=new ArrayList<>();
        ArrayList<Edge> arl1=new ArrayList<>();
        int a,b,c;
        for (int i = 0; i < N-1; i++) {
            StringTokenizer st=new StringTokenizer(br.readLine());
            a=Integer.parseInt(st.nextToken())-1;
            b=Integer.parseInt(st.nextToken())-1;
            c=Integer.parseInt(st.nextToken());
            if(c==0){
                arl0.add(new Edge(a,b));
            }else{
                arl1.add(new Edge(a,b));
            }
        }
        int[] rank0=new int[N];
        int[] rank1=new int[N];
        int[] par0=new int[N];
        int[] par1=new int[N];
        int[] siz0=new int[N];
        int[] siz1=new int[N];
        for (int i = 0; i < N; i++) {
            par0[i]=i; par1[i]=i; siz0[i]=1; siz1[i]=1;
        }
        for (Edge e : arl0) {
            int aa=find(e.a,par0);
            int bb=find(e.b,par0);
            if(aa!=bb){
                if(rank0[aa]>rank0[bb]){
                    par0[bb]=aa; siz0[aa]+=siz0[bb];
                }else if(rank0[aa]==rank0[bb]){
                    par0[bb]=aa; rank0[aa]++; siz0[aa]+=siz0[bb];
                }else{
                    par0[aa]=bb; siz0[bb]+=siz0[aa];
                }
            }
        }
        for (Edge e : arl1) {
            int aa=find(e.a,par1);
            int bb=find(e.b,par1);
            if(aa!=bb){
                if(rank1[aa]>rank1[bb]){
                    par1[bb]=aa; siz1[aa]+=siz1[bb];
                }else if(rank1[aa]==rank1[bb]){
                    par1[bb]=aa; rank1[aa]++; siz1[aa]+=siz1[bb];
                }else{
                    par1[aa]=bb; siz1[bb]+=siz1[aa];
                }
            }
        }
        long ans=0;
        for (int i = 0; i < N; i++) {
            ans+= (long) siz0[find(i,par0)]*siz1[find(i,par1)];

        }
        System.out.println(ans-N);
    }
    public static int find(int x, int[] par){
        if(par[x]==x)return x;
        int ans=find(par[x],par);
        par[x]=ans; return ans;
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Jenish
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        D01Tree solver = new D01Tree();
        solver.solve(1, in, out);
        out.close();
    }

    static class D01Tree {
        int[][] arr;
        long[][] size;

        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();

            size = new long[2][n + 1];
            Arrays.fill(size[0], 1);
            Arrays.fill(size[1], 1);
            arr = new int[2][n + 1];
            for (int i = 1; i <= n; i++) arr[0][i] = i;
            for (int i = 1; i <= n; i++) arr[1][i] = i;
            for (int i = 0; i < n - 1; i++) {
                int a = in.scanInt();
                int b = in.scanInt();
                int c = in.scanInt();
                if (root(a, c) != root(b, c)) w_union(a, b, c);
            }

            long ans = 0;
            for (int i = 1; i <= n; i++) {
                ans += size[0][i] * (size[0][i] - 1);
                ans += size[1][i] * (size[1][i] - 1);
                ans += (size[0][root(i, 0)] - 1) * (size[1][root(i, 1)] - 1);
            }
            out.println(ans);

        }

        int root(int i, int index) {
            while (arr[index][i] != i) {
                i = arr[index][i];
            }
            return i;
        }

        void w_union(int A, int B, int c) {
            int root_A = root(A, c);
            int root_B = root(B, c);
            if (size[c][root_A] < size[c][root_B]) {
                arr[c][root_A] = arr[c][root_B];
                size[c][root_B] += size[c][root_A];
                size[c][root_A] = 0;
            } else {
                arr[c][root_B] = arr[c][root_A];
                size[c][root_A] += size[c][root_B];
                size[c][root_B] = 0;
            }
        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public int scanInt() {
            int I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}


import java.io.BufferedReader;
// import java.io.FileInputStream;
// import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;

import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.util.Arrays.fill;
import static java.util.Arrays.sort;

public class Main {
    FastScanner in;
    PrintWriter out;

    class Pair {
        int v, c;

        Pair(int v, int c) {
            this.v = v;
            this.c = c;
        }
    }

    ArrayList<Pair>[] graph;
    long[][][] up, down;
    long ans;

    void dfs(int v, int p, int c) {
        if (p != -1) {
            if (c == 0) {
                up[0][0][v] += up[0][0][p] + down[0][0][p] + 1;
                up[1][0][v] += up[1][0][p] + down[1][0][p] + up[1][1][p] + down[1][1][p];
                ans += up[0][0][v] * 2 + up[1][0][v];
            } else if (c == 1) {
                up[1][1][v] += up[1][1][p] + down[1][1][p] + 1;
                up[0][1][v] += up[0][1][p] + down[0][1][p] + up[0][0][p] + down[0][0][p];
                ans += up[1][1][v] * 2 + up[0][1][v];
            } else
                c = 1 / 0;
        }

        for (Pair P : graph[v]) {
            if (P.v != p) {
                dfs(P.v, v, P.c);
                if (P.c == 0) {
                    down[0][0][v] += down[0][0][P.v] + 1;
                    down[1][0][v] += down[1][0][P.v] + down[1][1][P.v];
                } else if (P.c == 1) {
                    down[1][1][v] += down[1][1][P.v] + 1;
                    down[0][1][v] += down[0][1][P.v] + down[0][0][P.v];
                } else
                    c = 1 / 0;
            }
        }
    }

    private void solve() throws IOException {
        int n = in.nextInt();
        graph = new ArrayList[n];
        for (int i = 0; i < n; i++)
            graph[i] = new ArrayList<>();

        for (int i = 0; i < n - 1; i++) {
            int x = in.nextInt() - 1, y = in.nextInt() - 1, c = in.nextInt();
            graph[x].add(new Pair(y, c));
            graph[y].add(new Pair(x, c));
        }

        up = new long[2][2][n];
        down = new long[2][2][n];
        ans = 0;
        dfs(0, -1, -1);
        out.println(ans);
    }

    class FastScanner {
        StringTokenizer st;
        BufferedReader br;

        FastScanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        boolean hasNext() throws IOException {
            return br.ready() || (st != null && st.hasMoreTokens());
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        String nextLine() throws IOException {
            return br.readLine();
        }

        boolean hasNextLine() throws IOException {
            return br.ready();
        }
    }

    private void run() throws IOException {
        in = new FastScanner(System.in); // new FastScanner(new FileInputStream("input.txt"));
        out = new PrintWriter(System.out); // new PrintWriter(new FileOutputStream("output.txt"));

        solve();

        out.flush();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }
}


import java.io.BufferedReader;
// import java.io.FileInputStream;
// import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import java.util.StringTokenizer;

import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.util.Arrays.fill;
import static java.util.Arrays.sort;

public class Main {
    FastScanner in;
    PrintWriter out;

    class Pair {
        int v, c;

        Pair(int v, int c) {
            this.v = v;
            this.c = c;
        }
    }

    ArrayList<Pair>[] graph;
    long[][][] cnt;
    long ans;

    void dfs(int v, int p, int c) {
        if (p != -1) {
            if (c == 0) {
                ans += cnt[0][0][p] * 2 + cnt[1][0][p] + cnt[1][1][p];
                cnt[0][0][v] += cnt[0][0][p] + 1;
                cnt[1][0][v] += cnt[1][0][p] + cnt[1][1][p] + 1;
            } else if (c == 1) {
                ans += cnt[0][0][p] + cnt[0][1][p] + cnt[1][1][p] * 2;
                cnt[1][1][v] += cnt[1][1][p] + 1;
                cnt[0][1][v] += cnt[0][1][p] + cnt[0][0][p] + 1;
            } else
                c = 1 / 0;
        }
        for (Pair P : graph[v]) {
            if (P.v != p) {
                dfs(P.v, v, P.c);
            }
        }
    }

    private void solve() throws IOException {
        int n = in.nextInt();
        graph = new ArrayList[n];
        for (int i = 0; i < n; i++)
            graph[i] = new ArrayList<>();

        for (int i = 0; i < n - 1; i++) {
            int x = in.nextInt() - 1, y = in.nextInt() - 1, c = in.nextInt();
            graph[x].add(new Pair(y, c));
            graph[y].add(new Pair(x, c));
        }

        cnt = new long[2][2][n];
        dfs(0, -1, -1);
        ans = 0;
        out.println(ans);
    }

    class FastScanner {
        StringTokenizer st;
        BufferedReader br;

        FastScanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        boolean hasNext() throws IOException {
            return br.ready() || (st != null && st.hasMoreTokens());
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        String nextLine() throws IOException {
            return br.readLine();
        }

        boolean hasNextLine() throws IOException {
            return br.ready();
        }
    }

    private void run() throws IOException {
        in = new FastScanner(System.in); // new FastScanner(new FileInputStream("input.txt"));
        out = new PrintWriter(System.out); // new PrintWriter(new FileOutputStream("output.txt"));

        solve();

        out.flush();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }
}


//created by Whiplash99
import java.io.*;
import java.util.*;
public class D
{
    static class DSU
    {
        int parent[], size[];
        DSU(int N)
        {
            parent=new int[N];
            size=new int[N];
            for(int i=0;i<N;i++) make_set(i);
        }
        void make_set(int v)
        {
            parent[v]=v;
            size[v]=1;
        }
        int find_set(int v)
        {
            if(v==parent[v])
                return v;
            return parent[v]=find_set(parent[v]);
        }
        boolean union_sets(int a, int b)
        {
            a=find_set(a);
            b=find_set(b);

            if(a==b) return false;

            if(size[a]<size[b])
            {
                int tmp=a;
                a=b;
                b=tmp;
            }
            parent[b]=a;
            size[a]+=size[b];

            return true;
        }
    }
    public static void main(String[] args) throws IOException
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        int i,N;

        N=Integer.parseInt(br.readLine().trim());

        DSU zero=new DSU(N), one=new DSU(N);
        for(i=0;i<N-1;i++)
        {
            String s[]=br.readLine().trim().split(" ");
            int u=Integer.parseInt(s[0])-1;
            int v=Integer.parseInt(s[1])-1;
            int w=Integer.parseInt(s[2]);

            if(w==0) zero.union_sets(u,v);
            else one.union_sets(u,v);
        }

        long ans=0;
        for(i=0;i<N;i++)
        {
            int pZero=zero.find_set(i), pOne=one.find_set(i);

            if(pZero==i) ans+=(long)zero.size[i]*(zero.size[i]-1);
            if(pOne==i) ans+=(long)one.size[i]*(one.size[i]-1);

            ans+=(long)(zero.size[pZero]-1)*(one.size[pOne]-1);
        }
        System.out.println(ans);
    }
}


//created by Whiplash99
import java.io.*;
import java.util.*;
public class D
{
    static class DSU
    {
        int parent[], size[];
        DSU(int N)
        {
            parent=new int[N];
            size=new int[N];
            for(int i=0;i<N;i++) make_set(i);
        }
        void make_set(int v)
        {
            parent[v]=v;
            size[v]=1;
        }
        int find_set(int v)
        {
            if(v==parent[v])
                return v;
            return parent[v]=find_set(parent[v]);
        }
        boolean union_sets(int a, int b)
        {
            a=find_set(a);
            b=find_set(b);

            if(a==b) return false;

            if(size[a]<size[b])
            {
                int tmp=a;
                a=b;
                b=tmp;
            }
            parent[b]=a;
            size[a]+=size[b];

            return true;
        }
    }
    public static void main(String[] args) throws IOException
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        int i,N;

        N=Integer.parseInt(br.readLine().trim());

        DSU zero=new DSU(N), one=new DSU(N);
        for(i=0;i<N-1;i++)
        {
            String s[]=br.readLine().trim().split(" ");
            int u=Integer.parseInt(s[0])-1;
            int v=Integer.parseInt(s[1])-1;
            int w=Integer.parseInt(s[2]);

            if(w==0) zero.union_sets(u,v);
            else one.union_sets(u,v);
        }

        long ans=0;
        for(i=0;i<N;i++)
        {
            int pZero=zero.find_set(i), pOne=one.find_set(i);

            if(pZero==i) ans+=(long)zero.size[i]*(zero.size[i]-1); //ordered
            if(pOne==i) ans+=(long)one.size[i]*(one.size[i]-1); //ordered

            // Can go through 1 after 0, but not vice versa.
            // So, count only once.
            ans+=(long)(zero.size[pZero]-1)*(one.size[pOne]-1);
        }
        System.out.println(ans);
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author anand.oza
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        D01Tree solver = new D01Tree();
        solver.solve(1, in, out);
        out.close();
    }

    static class D01Tree {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();

            UnionFind zero = new UnionFind(n);
            UnionFind one = new UnionFind(n);

            for (int i = 0; i < n - 1; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                int c = in.nextInt();
                if (c == 0)
                    zero.union(a, b);
                else
                    one.union(a, b);
            }

            HashSet<Integer>[] onesReachableByZeros = new HashSet[n];
            for (int i = 0; i < n; i++) {
                onesReachableByZeros[i] = new HashSet<>();
            }

            for (int i = 0; i < n; i++) {
                onesReachableByZeros[zero.rep(i)].add(one.rep(i));
            }

            long answer = 0;
            for (int i = 0; i < n; i++) {
                if (zero.rep(i) == i) {
                    for (int j : onesReachableByZeros[i]) {
                        answer += ((long) zero.size(i)) * one.size(j);
                    }
                    answer -= zero.size(i);
                }
            }

            out.println(answer);
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }

    static class UnionFind {
        private int[] __rep;
        private int[] __size;

        public UnionFind(int n) {
            __rep = new int[n];
            __size = new int[n];
            for (int i = 0; i < n; i++) {
                __rep[i] = i;
                __size[i] = 1;
            }
        }

        public int rep(int x) {
            if (__rep[x] == x) {
                return x;
            }

            int r = rep(__rep[x]);
            __rep[x] = r;
            return r;
        }

        public int size(int x) {
            return __size[rep(x)];
        }

        public void union(int x, int y) {
            x = rep(x);
            y = rep(y);

            if (x == y) {
                return;
            }

            if (size(x) < size(y)) {
                int t = x;
                x = y;
                y = t;
            }

            // now size(x) >= size(y)

            __rep[y] = x;
            __size[x] += __size[y];
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author anand.oza
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        D01Tree solver = new D01Tree();
        solver.solve(1, in, out);
        out.close();
    }

    static class D01Tree {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();

            UnionFind zero = new UnionFind(n);
            UnionFind one = new UnionFind(n);

            for (int i = 0; i < n - 1; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                int c = in.nextInt();
                if (c == 0)
                    zero.union(a, b);
                else
                    one.union(a, b);
            }

            HashSet<Integer>[] onesReachableByZeros = new HashSet[n];
            for (int i = 0; i < n; i++) {
                onesReachableByZeros[i] = new HashSet<>();
            }

            for (int i = 0; i < n; i++) {
                onesReachableByZeros[zero.rep(i)].add(one.rep(i));
            }

            long answer = 0;
            for (int i = 0; i < n; i++) {
                if (zero.rep(i) == i) {
                    for (int j : onesReachableByZeros[i]) {
                        answer += zero.size(i) * one.size(j);
                    }
                    answer -= zero.size(i);
                }
            }

            out.println(answer);
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }

    static class UnionFind {
        private int[] __rep;
        private int[] __size;

        public UnionFind(int n) {
            __rep = new int[n];
            __size = new int[n];
            for (int i = 0; i < n; i++) {
                __rep[i] = i;
                __size[i] = 1;
            }
        }

        public int rep(int x) {
            if (__rep[x] == x) {
                return x;
            }

            int r = rep(__rep[x]);
            __rep[x] = r;
            return r;
        }

        public int size(int x) {
            return __size[rep(x)];
        }

        public void union(int x, int y) {
            x = rep(x);
            y = rep(y);

            if (x == y) {
                return;
            }

            if (size(x) < size(y)) {
                int t = x;
                x = y;
                y = t;
            }

            // now size(x) >= size(y)

            __rep[y] = x;
            __size[x] += __size[y];
        }

    }
}


import java.io.*;
import java.util.*;
/*
 * @ author : - typedef_2000
 */
public class Main {
     static ArrayList a[]=new ArrayList[3000001];
     static boolean visited[]=new boolean [3000001];
     static long dp[][]=new long[300001][2];
     static long suf[]=new long[300001];
     static Vector<Integer>color=new Vector<>();
     static void dfs(int n,int c) {
    	 color.add(n);
    	 visited[n]=true;
    	 for(int i=0;i<a[n].size();i++) {
    		 pair id=(pair) a[n].get(i);
    		 if(!visited [id.x] &&  id.y==c) {
    			 dfs(id.x,c);
    		 }
    	 }
     }
     static void dfs1(int n) {
    	 visited[n]=true;
    	 for(int i=0;i<a[n].size();i++) {
    		 pair id=(pair) a[n].get(i);
    		 if(!visited [id.x] ) {
    			 dfs1(id.x);
    			 if(id.y==0) {
    				 if(suf[id.x]==0)
    				 {
    					 suf[n]+=dp[id.x][1];
    				 }
    				 else
    					 suf[n]+=suf[id.x];
    			 }
    		 }
    	 }
     }
     static void dfs2(int n) {
    	 visited[n]=true;
    	 for(int i=0;i<a[n].size();i++) {
    		 pair id=(pair) a[n].get(i);
    		 if(!visited [id.x] ) {
    			if(id.y==0) {
    				dp[id.x][1]+=(suf[n]-suf[id.x]+dp[n][1]-dp[id.x][1]);
    			}
    			 dfs2(id.x);
    	     }
    	 }
     }
     public static void main(String[]args)
    {
        InputReader in=new InputReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        int n=in.nextInt();
        for(int i=0;i<=n;i++) {
        	a[i]=new ArrayList<Integer>();
        }
        for(int i=0;i<n-1;i++) {
        	int x=in.nextInt();
        	int y=in.nextInt();
        	int c=in.nextInt();
            a[x].add(new pair(y,c));
            a[y].add(new pair(x,c));
        }
        for(int i=1;i<=n;i++) {
        	if(!visited[i])
        	{
        		dfs(i,0);
        		for(int j=0;j<color.size();j++) {
        			int got=color.get(j);
        			dp[got][0]=color.size()-1;
        		}
        		color.clear();
        	}
        }
        Arrays.fill(visited, false);
        for(int i=1;i<=n;i++) {
        	if(!visited[i])
        	{
        		dfs(i,1);
        		for(int j=0;j<color.size();j++) {
        			int got=color.get(j);
        			dp[got][1]=color.size()-1;
        		}
        		color.clear();
        	}
        }
        Arrays.fill(visited, false);
        dfs1(1);
        Arrays.fill(visited, false);
        dfs2(1);
        long ans=0;
        for(int i=1;i<=n;i++) {
        	ans+=dp[i][0];
        	ans+=dp[i][1];
        	ans+=suf[i];
        }
        pw.println(ans);
        pw.flush();
        pw.close();

    }
    private static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
   static class InputReader
        {
        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream)
        {
            this.stream = stream;
        }
        public int snext()
        {
            if (snumChars == -1)
                throw new InputMismatchException();
            if (curChar >= snumChars)
            {
                curChar = 0;
                try
                {
                    snumChars = stream.read(buf);
                }

                catch (IOException e)
                {
                    throw new InputMismatchException();
                }

                if (snumChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int nextInt()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            int res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long nextLong()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            long res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int[] nextIntArray(int n)
        {
            int a[] = new int[n];
            for (int i = 0; i < n; i++)
            {
                a[i] = nextInt();
            }
            return a;
        }
        static class tri implements Comparable<tri> {
            int p, c, l;

            tri(int p, int c, int l) {
                this.p = p;
                this.c = c;
                this.l = l;
            }

            public int compareTo(tri o) {
                return Integer.compare(l, o.l);
            }
        }

        public String readString()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = snext();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public String nextLine()
        {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = snext();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c)
        {
            return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter
        {
            public boolean isSpaceChar(int ch);
        }
    }
   public static long modularExponentiation(long x,long n,long M)
   {
       long result=1;
       while(n>0)
       {
           if(n % 2 ==1)
               result=(result%M * x%M)%M;
           x=(x%M * x%M)%M;
           n=n/2;
       }
       return result;
   }

   public static long modInverse(int A,int M)
   {
       return modularExponentiation(A,M-2,M);
   }

   public static long modInverse(long A,long M)
   {
       return modularExponentiation(A,M-2,M);
   }
   static class pair implements Comparable<pair>
   {
       Integer x, y;
       pair(int x,int y)
       {
           this.x=x;
           this.y=y;
       }

       public int compareTo(pair o) {
           int result = x.compareTo(o.x);
           if(result==0)
               result = y.compareTo(o.y);

           return result;
       }

       public String toString()
       {
           return x+" "+y;
       }

       public boolean equals(Object o)
       {
           if (o instanceof pair)
          {
               pair p = (pair)o;
               return (Math.abs(p.x-x)==0 && Math.abs(p.y-y)==0);
           }
           return false;
       }

       public int hashCode()
       {
           return new Long(x).hashCode()*31 + new Long(y).hashCode();
       }
   }
    public static long GCD(long a,long b)
    {
        if(b==0)
            return a;
        else
            return GCD(b,a%b);
    }
    public static long[] shuffle(long[] a, Random gen){
        for(int i = 0, n = a.length;i < n;i++){
            int ind = gen.nextInt(n-i)+i;
            long d = a[i];
            a[i] = a[ind];
            a[ind] = d;
        }
        return a;
    }

}


import java.io.*;
import java.util.*;
public class Main {
     static ArrayList a[]=new ArrayList[3000001];
     static ArrayList b[]=new ArrayList[3000001];
     static boolean visited[]=new boolean [3000001];
     static long dp[][]=new long[300001][2];
     static int p[]=new int[300001];
     static Vector<Integer>color=new Vector<>();
     static void dfs(int n) {
    	 color.add(n);
    	 visited[n]=true;
    	 for(int i=0;i<b[n].size();i++) {
    		int id=(int)b[n].get(i);
    		 if(!visited [id]) {
    			 dfs(id);
    		 }
    	 }
     }
     static void dfs1(int n) {
    	 color.add(n);
    	 visited[n]=true;
    	 for(int i=0;i<a[n].size();i++) {
    		int id=(int)a[n].get(i);
    		 if(!visited [id]) {
    			 dfs1(id);
    		 }
    	 }
     }

     public static void main(String[]args)
    {
        InputReader in=new InputReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        int n=in.nextInt();
        for(int i=0;i<=n;i++) {
        	a[i]=new ArrayList<Integer>();
        	b[i]=new ArrayList<Integer>();
        }
        for(int i=0;i<n-1;i++) {
        	int x=in.nextInt();
        	int y=in.nextInt();
        	int c=in.nextInt();
            if(c==1) {
            	b[x].add(y);
            	b[y].add(x);
            }
            else
            {
            	a[x].add(y);
            	a[y].add(x);
            }
        }
        int parent=1;
        for(int i=1;i<=n;i++) {

        	if(!visited[i])
        	{
        		dfs(i);
         		if(color.size()==1)
        		{
            		color.clear();
        			continue;
        		}
        		for(int j=0;j<color.size();j++) {
        			int got=color.get(j);
        			p[got]=parent;
        			dp[got][1]=color.size()-1;
        		}
        		parent++;
        		color.clear();
        	}
        }
        Arrays.fill(visited, false);
        for(int i=1;i<=n;i++) {
        	if(!visited[i]) {
        		dfs1(i);
        		if(color.size()==1)
        		{
            		color.clear();
        			continue;
        		}
        		long ans=0;
        		TreeSet<Integer>tr=new TreeSet<>();
        		for(int j=0;j<color.size();j++) {
        			int got=color.get(j);
        			for(int k=0;k<b[got].size();k++) {
        				int idx=(int) b[got].get(k);
        				if(!tr.contains(p[idx])) {
        					ans+=dp[idx][1];
        					tr.add(p[idx]);
        				}
        			}
        		}
        		for(int j=0;j<color.size();j++) {
        			int got=color.get(j);
        			dp[got][0]=color.size()-1+ans-dp[got][1];
        		}
        		color.clear();
        	}

        }
        long ans=0;
        for(int i=1;i<=n;i++) {
        	ans+=dp[i][0];
        	ans+=dp[i][1];
        }
        pw.println(ans);
        pw.flush();
        pw.close();

    }
    private static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
   static class InputReader
        {
        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream)
        {
            this.stream = stream;
        }
        public int snext()
        {
            if (snumChars == -1)
                throw new InputMismatchException();
            if (curChar >= snumChars)
            {
                curChar = 0;
                try
                {
                    snumChars = stream.read(buf);
                }

                catch (IOException e)
                {
                    throw new InputMismatchException();
                }

                if (snumChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int nextInt()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            int res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long nextLong()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            long res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public int[] nextIntArray(int n)
        {
            int a[] = new int[n];
            for (int i = 0; i < n; i++)
            {
                a[i] = nextInt();
            }
            return a;
        }
        static class tri implements Comparable<tri> {
            int p, c, l;

            tri(int p, int c, int l) {
                this.p = p;
                this.c = c;
                this.l = l;
            }

            public int compareTo(tri o) {
                return Integer.compare(l, o.l);
            }
        }

        public String readString()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = snext();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public String nextLine()
        {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = snext();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c)
        {
            return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter
        {
            public boolean isSpaceChar(int ch);
        }
    }
   public static long modularExponentiation(long x,long n,long M)
   {
       long result=1;
       while(n>0)
       {
           if(n % 2 ==1)
               result=(result%M * x%M)%M;
           x=(x%M * x%M)%M;
           n=n/2;
       }
       return result;
   }

   public static long modInverse(int A,int M)
   {
       return modularExponentiation(A,M-2,M);
   }

   public static long modInverse(long A,long M)
   {
       return modularExponentiation(A,M-2,M);
   }
   static class pair implements Comparable<pair>
   {
       Integer x, y;
       pair(int x,int y)
       {
           this.x=x;
           this.y=y;
       }

       public int compareTo(pair o) {
           int result = x.compareTo(o.x);
           if(result==0)
               result = y.compareTo(o.y);

           return result;
       }

       public String toString()
       {
           return x+" "+y;
       }

       public boolean equals(Object o)
       {
           if (o instanceof pair)
          {
               pair p = (pair)o;
               return (Math.abs(p.x-x)==0 && Math.abs(p.y-y)==0);
           }
           return false;
       }

       public int hashCode()
       {
           return new Long(x).hashCode()*31 + new Long(y).hashCode();
       }
   }
    public static long GCD(long a,long b)
    {
        if(b==0)
            return a;
        else
            return GCD(b,a%b);
    }
    public static long[] shuffle(long[] a, Random gen){
        for(int i = 0, n = a.length;i < n;i++){
            int ind = gen.nextInt(n-i)+i;
            long d = a[i];
            a[i] = a[ind];
            a[ind] = d;
        }
        return a;
    }

}