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

public class ZeroOneTree {
    public static Node[] nodes;
    public static void main(String[] args) throws IOException{
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        int n = Integer.parseInt(f.readLine());
        nodes = new Node[n+1];
        LinkedList<Edge>[] edges = new LinkedList[n+1];
        for(int i = 0; i <= n; i++){
            nodes[i] = new Node(i);
        }
        for(int i = 0; i <= n; i++){
            edges[i] = new LinkedList<Edge>();
        }
        for(int i = 0; i < n-1; i++){
            StringTokenizer st = new StringTokenizer(f.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());
            edges[a].add(new Edge(b, c));
            edges[b].add(new Edge(a, c));
        }
        HashSet<Integer> visited = new HashSet<Integer>();
        LinkedList<Integer> q = new LinkedList<Integer>();
        q.add(1);
        while(!q.isEmpty()){
            int temp = q.poll();
            if(visited.contains(temp)) continue;
            visited.add(temp);
            for(Edge e: edges[temp]){
                if(!visited.contains(e.dest)){
                    nodes[temp].children.add(new Edge(e.dest, e.val));
                    q.add(e.dest);
                }
            }
        }
        ArrayList<Integer> postorder = postorder(nodes[1]);
        for(int nid: postorder){
            if(nodes[nid].children.size() == 0) nodes[nid].sum = 0;
            for(int i = 0; i < nodes[nid].children.size(); i++){
                nodes[nid].sum += nodes[nodes[nid].children.get(i).dest].sum;
                if(nodes[nid].children.get(i).val == 0){
                    nodes[nid].onezero += nodes[nodes[nid].children.get(i).dest].one;
                    nodes[nid].onezero += nodes[nodes[nid].children.get(i).dest].onezero;
                    nodes[nid].zero += nodes[nodes[nid].children.get(i).dest].zero+1;
                    nodes[nodes[nid].children.get(i).dest].onezero += nodes[nodes[nid].children.get(i).dest].one;
                    nodes[nodes[nid].children.get(i).dest].one = 0;
                    nodes[nodes[nid].children.get(i).dest].zeroone = 0;
                    nodes[nodes[nid].children.get(i).dest].zero += 1;
                }else{
                    nodes[nid].zeroone += nodes[nodes[nid].children.get(i).dest].zero;
                    nodes[nid].zeroone += nodes[nodes[nid].children.get(i).dest].zeroone;
                    nodes[nid].one += nodes[nodes[nid].children.get(i).dest].one+1;
                    nodes[nodes[nid].children.get(i).dest].zeroone += nodes[nodes[nid].children.get(i).dest].zero;
                    nodes[nodes[nid].children.get(i).dest].zero = 0;
                    nodes[nodes[nid].children.get(i).dest].onezero = 0;
                    nodes[nodes[nid].children.get(i).dest].one += 1;
                }
            }
            nodes[nid].sum += 2*nodes[nid].zero;
            nodes[nid].sum += 2*nodes[nid].one;
            nodes[nid].sum += nodes[nid].zeroone;
            nodes[nid].sum += nodes[nid].onezero;

            for(int i = 1; i < nodes[nid].children.size(); i++){
                nodes[nid].sum += 2*nodes[nodes[nid].children.get(0).dest].zero*nodes[nodes[nid].children.get(i).dest].zero;
                nodes[nid].sum += 2*nodes[nodes[nid].children.get(0).dest].one*nodes[nodes[nid].children.get(i).dest].one;
                nodes[nid].sum += nodes[nodes[nid].children.get(0).dest].zero*nodes[nodes[nid].children.get(i).dest].one;
                nodes[nid].sum += nodes[nodes[nid].children.get(0).dest].one*nodes[nodes[nid].children.get(i).dest].zero;
                nodes[nid].sum += nodes[nodes[nid].children.get(0).dest].zeroone*nodes[nodes[nid].children.get(i).dest].one;
                nodes[nid].sum += nodes[nodes[nid].children.get(0).dest].one*nodes[nodes[nid].children.get(i).dest].zeroone;
                nodes[nid].sum += nodes[nodes[nid].children.get(0).dest].onezero*nodes[nodes[nid].children.get(i).dest].zero;
                nodes[nid].sum += nodes[nodes[nid].children.get(0).dest].zero*nodes[nodes[nid].children.get(i).dest].onezero;
                nodes[nodes[nid].children.get(0).dest].zero += nodes[nodes[nid].children.get(i).dest].zero;
                nodes[nodes[nid].children.get(0).dest].one += nodes[nodes[nid].children.get(i).dest].one;
                nodes[nodes[nid].children.get(0).dest].zeroone += nodes[nodes[nid].children.get(i).dest].zeroone;
                nodes[nodes[nid].children.get(0).dest].onezero += nodes[nodes[nid].children.get(i).dest].onezero;
            }
        }
        out.println(nodes[1].sum);
        out.close();

    }

    static class Pair {
        public Node node;
        public int childrenIndex;
        public Pair(Node _node, int _childrenIndex)
        {
            node = _node;
            childrenIndex = _childrenIndex;
        }
    }

    // We will keep the start index as 0,
    // because first we always
    // process the left most children
    public static int currentRootIndex = 0;
    public static Stack<Pair> stack = new Stack<Pair>();
    public static ArrayList<Integer> postorderTraversal =
            new ArrayList<Integer>();

    // Function to perform iterative postorder traversal
    public static ArrayList<Integer> postorder(Node root)
    {
        while (root != null || !stack.isEmpty()) {
            if (root != null) {

                // Push the root and it's index
                // into the stack
                stack.push(new Pair(root, currentRootIndex));
                currentRootIndex = 0;

                // If root don't have any children's that
                // means we are already at the left most
                // node, so we will mark root as null
                if (root.children.size() >= 1) {
                    root = nodes[root.children.get(0).dest];
                }
                else {
                    root = null;
                }
                continue;
            }

            // We will pop the top of the stack and
            // add it to our answer
            Pair temp = stack.pop();
            postorderTraversal.add(temp.node.id);

            // Repeatedly we will the pop all the
            // elements from the stack till popped
            // element is last children of top of
            // the stack
            while (!stack.isEmpty() && temp.childrenIndex ==
                    stack.peek().node.children.size() - 1) {
                temp = stack.pop();

                postorderTraversal.add(temp.node.id);
            }

            // If stack is not empty, then simply assign
            // the root to the next children of top
            // of stack's node
            if (!stack.isEmpty()) {
                root = nodes[stack.peek().node.children.get(temp.childrenIndex + 1).dest];
                currentRootIndex = temp.childrenIndex + 1;
            }
        }

        return postorderTraversal;
    }

    static class Node{
        public int id;
        public ArrayList<Edge> children;
        public long sum;
        public long zero;
        public long one;
        public long zeroone;
        public long onezero;

        public Node(int i){
            id = i;
            children = new ArrayList<Edge>();
            sum = 0;
            zero = 0;
            one = 0;
            zeroone = 0;
            onezero = 0;
        }
    }
    static class Edge{
        public int dest;
        public int val;

        public Edge(int d, int v){
            dest = d;
            val = v;
        }
    }
}


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

public class ZeroOneTree {
    public static Node[] nodes;
    public static void main(String[] args) throws IOException{
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        int n = Integer.parseInt(f.readLine());
        nodes = new Node[n+1];
        LinkedList<Edge>[] edges = new LinkedList[n+1];
        for(int i = 0; i <= n; i++){
            nodes[i] = new Node(i);
        }
        for(int i = 0; i <= n; i++){
            edges[i] = new LinkedList<Edge>();
        }
        for(int i = 0; i < n-1; i++){
            StringTokenizer st = new StringTokenizer(f.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());
            edges[a].add(new Edge(b, c));
            edges[b].add(new Edge(a, c));
        }
        HashSet<Integer> visited = new HashSet<Integer>();
        LinkedList<Integer> q = new LinkedList<Integer>();
        q.add(1);
        while(!q.isEmpty()){
            int temp = q.poll();
            if(visited.contains(temp)) continue;
            visited.add(temp);
            for(Edge e: edges[temp]){
                if(!visited.contains(e.dest)){
                    nodes[temp].children.add(new Edge(e.dest, e.val));
                    q.add(e.dest);
                }
            }
        }

        long ans = dfs(1);
        out.println(ans);
        out.close();

    }

    public static long dfs(int n){
        long sum = 0;
        if(nodes[n].children.size() == 0) return 0;
        for(int i = 0; i < nodes[n].children.size(); i++){
            sum += dfs(nodes[n].children.get(i).dest);
            if(nodes[n].children.get(i).val == 0){
                nodes[n].onezero += nodes[nodes[n].children.get(i).dest].one;
                nodes[n].onezero += nodes[nodes[n].children.get(i).dest].onezero;
                nodes[n].zero += nodes[nodes[n].children.get(i).dest].zero+1;
                nodes[nodes[n].children.get(i).dest].onezero += nodes[nodes[n].children.get(i).dest].one;
                nodes[nodes[n].children.get(i).dest].one = 0;
                nodes[nodes[n].children.get(i).dest].zeroone = 0;
                nodes[nodes[n].children.get(i).dest].zero += 1;
            }else{
                nodes[n].zeroone += nodes[nodes[n].children.get(i).dest].zero;
                nodes[n].zeroone += nodes[nodes[n].children.get(i).dest].zeroone;
                nodes[n].one += nodes[nodes[n].children.get(i).dest].one+1;
                nodes[nodes[n].children.get(i).dest].zeroone += nodes[nodes[n].children.get(i).dest].zero;
                nodes[nodes[n].children.get(i).dest].zero = 0;
                nodes[nodes[n].children.get(i).dest].onezero = 0;
                nodes[nodes[n].children.get(i).dest].one += 1;
            }
        }
        sum += 2*nodes[n].zero;
        sum += 2*nodes[n].one;
        sum += nodes[n].zeroone;
        sum += nodes[n].onezero;

        for(int i = 1; i < nodes[n].children.size(); i++){
            sum += 2*nodes[nodes[n].children.get(0).dest].zero*nodes[nodes[n].children.get(i).dest].zero;
            sum += 2*nodes[nodes[n].children.get(0).dest].one*nodes[nodes[n].children.get(i).dest].one;
            sum += nodes[nodes[n].children.get(0).dest].zero*nodes[nodes[n].children.get(i).dest].one;
            sum += nodes[nodes[n].children.get(0).dest].one*nodes[nodes[n].children.get(i).dest].zero;
            sum += nodes[nodes[n].children.get(0).dest].zeroone*nodes[nodes[n].children.get(i).dest].one;
            sum += nodes[nodes[n].children.get(0).dest].one*nodes[nodes[n].children.get(i).dest].zeroone;
            sum += nodes[nodes[n].children.get(0).dest].onezero*nodes[nodes[n].children.get(i).dest].zero;
            sum += nodes[nodes[n].children.get(0).dest].zero*nodes[nodes[n].children.get(i).dest].onezero;
            nodes[nodes[n].children.get(0).dest].zero += nodes[nodes[n].children.get(i).dest].zero;
            nodes[nodes[n].children.get(0).dest].one += nodes[nodes[n].children.get(i).dest].one;
            nodes[nodes[n].children.get(0).dest].zeroone += nodes[nodes[n].children.get(i).dest].zeroone;
            nodes[nodes[n].children.get(0).dest].onezero += nodes[nodes[n].children.get(i).dest].onezero;
        }

        return sum;
    }
    static class Node{
        public int id;
        public ArrayList<Edge> children;
        public long zero;
        public long one;
        public long zeroone;
        public long onezero;

        public Node(int i){
            id = i;
            children = new ArrayList<Edge>();
            zero = 0;
            one = 0;
            zeroone = 0;
            onezero = 0;
        }
    }
    static class Edge{
        public int dest;
        public int val;

        public Edge(int d, int v){
            dest = d;
            val = v;
        }
    }
}


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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
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);
        D01Derevo solver = new D01Derevo();
        solver.solve(1, in, out);
        out.close();
    }

    static class D01Derevo {

        long ans = 0;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            D01Derevo.Vertex[] vs = D01Derevo.Vertex.emptyGraph(n);
            for (int i = 1; i < n; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                int color = in.nextInt();
                vs[a].adj.add(new D01Derevo.Edge(vs[b], color));
                vs[b].adj.add(new D01Derevo.Edge(vs[a], color));
            }
            ans = 0;
            doit(vs[0], null);
            out.println(ans);
        }

        private void doit(D01Derevo.Vertex v, D01Derevo.Vertex prev) {
            for (D01Derevo.Edge e : v.adj) {
                if (e.to == prev) {
                    continue;
                }
                doit(e.to, v);
            }
            long ones = 0;
            long zeros = 0;
            long zeroOnes = 0;
            long oneZeros = 0;
            for (D01Derevo.Edge e : v.adj) {
                if (e.to == prev) {
                    continue;
                }
                if (e.color == 1) {
                    ones += e.to.ones + 1;
                    zeroOnes += e.to.zeroOnes + e.to.zeros;
                } else {
                    zeros += e.to.zeros + 1;
                    oneZeros += e.to.oneZeros + e.to.ones;
                }
            }
            v.ones = ones;
            v.zeros = zeros;
            v.zeroOnes = zeroOnes;
            v.oneZeros = oneZeros;

            ans += 2 * ones + 2 * zeros + zeroOnes + oneZeros;
            for (D01Derevo.Edge e : v.adj) {
                if (e.to == prev) {
                    continue;
                }
                if (e.color == 1) {
                    ans += (e.to.ones + e.to.zeroOnes + e.to.zeros + 1) * (ones - e.to.ones - 1);
                } else {
                    ans += (e.to.zeros + 1) * (zeros - e.to.zeros - 1 + oneZeros - e.to.oneZeros - e.to.ones + ones);
                }
            }
        }

        public static class Vertex {

            long ones = -1;
            long zeros = -1;
            long zeroOnes = -1;
            long oneZeros = -1;
            int idx;
            List<D01Derevo.Edge> adj = new ArrayList<>();

            public static D01Derevo.Vertex[] emptyGraph(int n) {
                D01Derevo.Vertex[] vs = new D01Derevo.Vertex[n];
                for (int i = 0; i < n; i++) {
                    vs[i] = new D01Derevo.Vertex();
                    vs[i].idx = i;
                }
                return vs;
            }
        }

        public static class Edge {

            D01Derevo.Vertex to;
            int color;

            public Edge(D01Derevo.Vertex to, int color) {
                this.to = to;
                this.color = color;
            }
        }
    }

    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());
        }
    }
}


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

/*
Solution Sketch:
*/

public class tree {

    static final boolean stdin = true;
    static final String filename = "";
    static FastScanner br;
    static PrintWriter pw;

    public static void main(String[] args) throws IOException {

        if (stdin) {
            br = new FastScanner();
            pw = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            br = new FastScanner(filename + ".in");
            pw = new PrintWriter(new FileWriter(filename + ".out"));
        }

        X solver = new X();
        solver.solve(br, pw);
    }

    static class X {
        public void solve(FastScanner br, PrintWriter pw) throws IOException {
            int N = br.nextInt();
            DSU zero = new DSU(N);
            DSU one = new DSU(N);
            int CC = N;
            for (int i = 0; i < N - 1; i++) {
                int x = br.nextInt(); int y = br.nextInt(); int c = br.nextInt();
                x--; y--;
                if (c == 0) {
                    zero.union(x, y);
                }
                else {
                    one.union(x, y);
                    CC--;
                }
//                for(int j = 0; j < N; j++){
//                    pw.println(j + " " + zero.find(j) + " " + one.find(j));
//                }
//                pw.println();
            }

            long ans = 0;
            boolean[] vis0 = new boolean[N];
            boolean[] vis1 = new boolean[N];
            for(int i = 0; i < N; i++){ //deal with CC's of size 0 and 1
                if(!vis0[zero.find(i)]){
                    int p = zero.find(i);
                    if(zero.sz(p) > 1) {
//                        pw.println("zero: " + p + " " + zero.sz(p));
                        ans += (zero.sz(p) * (zero.sz(p)-1));
                    }
                    vis0[p] = true;
                }
                if(!vis1[one.find(i)]){
                    int p = one.find(i);
                    if(one.sz(p) > 1) {
//                        pw.println("one: " + p + " " + one.sz(p));
                        ans += (one.sz(p) * (one.sz(p)-1));
                    }
                    vis1[p] = true;
                }
                }
//            pw.println(ans);

            //deal with 0-1 case, for all CC of 1 multiply by number of other CC's (start at N then every merge --
            vis1 = new boolean[N];
            for(int i = 0; i < N; i++){
                int p = one.find(i);
                if(one.sz(p) > 1 && !vis1[p]){
                    ans += ((CC-1) * (one.sz(p)-1));
                    vis1[p] = true;
                }
            }
            pw.println(ans);
            pw.close();
        }
        class DSU{
             int N;
             int[] par, size;
             DSU(int N){
                this.N = N;
                par = new int[N]; size = new int[N];
                for(int i = 0; i < N; i++) {
                    par[i] = i;
                    size[i] = 1;
                }
            }
             int find(int x){ //wrong?
                if(x == par[x]){
                    return x;
                }
                return par[x] = find(par[x]);
            }
              void union(int x, int y){
                int p = find(x); int q = find(y);
                if(p != q){
                    if(size[p] < size[q]){
                        int temp = p;
                        p = q;
                        q = temp;
                    }
                    par[q] = p;
                    size[p] += size[q];

                }
            }
              int sz(int x){ return size[x];}
        }
    }

    //fastscanner class
    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(String s) {
            try {
                br = new BufferedReader(new FileReader(s));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }

}


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

/*
Solution Sketch:
*/

public class tree {

    static final boolean stdin = true;
    static final String filename = "";
    static FastScanner br;
    static PrintWriter pw;

    public static void main(String[] args) throws IOException {

        if (stdin) {
            br = new FastScanner();
            pw = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            br = new FastScanner(filename + ".in");
            pw = new PrintWriter(new FileWriter(filename + ".out"));
        }

        X solver = new X();
        solver.solve(br, pw);
    }

    static class X {
        public void solve(FastScanner br, PrintWriter pw) throws IOException {
            int N = br.nextInt();
            DSU zero = new DSU(N);
            DSU one = new DSU(N);
            for (int i = 0; i < N - 1; i++) {
                int x = br.nextInt(); int y = br.nextInt(); int c = br.nextInt();
                x--; y--;
                if (c == 0) {
                    zero.union(x, y);
                }
                else {
                    one.union(x, y);
                }
//                for(int j = 0; j < N; j++){
//                    pw.println(j + " " + zero.find(j) + " " + one.find(j));
//                }
//                pw.println();
            }

            long ans = 0;
            boolean[] vis0 = new boolean[N];
            boolean[] vis1 = new boolean[N];
            for(int i = 0; i < N; i++){ //deal with CC's of size 0 and 1
                if(!vis0[zero.find(i)]){
                    int p = zero.find(i);
                    if(zero.sz(p) > 1) {
//                        pw.println("zero: " + p + " " + zero.sz(p));
                        ans += ((long)zero.sz(p) * ((long)(zero.sz(p)-1)));
                    }
                    vis0[p] = true;
                }
                if(!vis1[one.find(i)]){
                    int p = one.find(i);
                    if(one.sz(p) > 1) {
//                        pw.println("one: " + p + " " + one.sz(p));
                        ans += ((long)one.sz(p) * (long)(one.sz(p)-1));
                    }
                    vis1[p] = true;
                }
                }
//            pw.println(ans);

            //deal with 0-1 case, for all CC of 1 multiply by number of other CC's (start at N then every merge --
            for(int i = 0; i < N; i++){
                int p = one.find(i); int q = zero.find(i);
                    ans += ((long)(one.sz(p)-1) * (long)(zero.sz(q)-1));
            }
            pw.println(ans);
            pw.close();
        }
        class DSU{
             int N;
             int[] par, size;
             DSU(int N){
                this.N = N;
                par = new int[N]; size = new int[N];
                for(int i = 0; i < N; i++) {
                    par[i] = i;
                    size[i] = 1;
                }
            }
             int find(int x){ //wrong?
                if(x == par[x]){
                    return x;
                }
                return par[x] = find(par[x]);
            }
              void union(int x, int y){
                int p = find(x); int q = find(y);
                if(p != q){
                    if(size[p] < size[q]){
                        int temp = p;
                        p = q;
                        q = temp;
                    }
                    par[q] = p;
                    size[p] += size[q];

                }
            }
              int sz(int x){ return size[x];}
        }
    }

    //fastscanner class
    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(String s) {
            try {
                br = new BufferedReader(new FileReader(s));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }

}


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

/*
Solution Sketch:
*/

public class tree {

    static final boolean stdin = true;
    static final String filename = "";
    static FastScanner br;
    static PrintWriter pw;

    public static void main(String[] args) throws IOException {

        if (stdin) {
            br = new FastScanner();
            pw = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            br = new FastScanner(filename + ".in");
            pw = new PrintWriter(new FileWriter(filename + ".out"));
        }

        X solver = new X();
        solver.solve(br, pw);
    }

    static class X {
        public void solve(FastScanner br, PrintWriter pw) throws IOException {
            int N = br.nextInt();
            DSU zero = new DSU(N);
            DSU one = new DSU(N);
            for (int i = 0; i < N - 1; i++) {
                int x = br.nextInt(); int y = br.nextInt(); int c = br.nextInt();
                x--; y--;
                if (c == 0) {
                    zero.union(x, y);
                }
                else {
                    one.union(x, y);
                }
//                for(int j = 0; j < N; j++){
//                    pw.println(j + " " + zero.find(j) + " " + one.find(j));
//                }
//                pw.println();
            }

            long ans = 0;
            boolean[] vis0 = new boolean[N];
            boolean[] vis1 = new boolean[N];
            for(int i = 0; i < N; i++){ //deal with CC's of size 0 and 1
                if(!vis0[zero.find(i)]){
                    int p = zero.find(i);
                    if(zero.sz(p) > 1) {
//                        pw.println("zero: " + p + " " + zero.sz(p));
                        ans += (zero.sz(p) * (zero.sz(p)-1));
                    }
                    vis0[p] = true;
                }
                if(!vis1[one.find(i)]){
                    int p = one.find(i);
                    if(one.sz(p) > 1) {
//                        pw.println("one: " + p + " " + one.sz(p));
                        ans += (one.sz(p) * (one.sz(p)-1));
                    }
                    vis1[p] = true;
                }
                }
//            pw.println(ans);

            //deal with 0-1 case, for all CC of 1 multiply by number of other CC's (start at N then every merge --
            vis1 = new boolean[N]; vis0 = new boolean[N];
            for(int i = 0; i < N; i++){
                int p = one.find(i); int q = zero.find(i);
                if(one.sz(p) > 1 && zero.sz(q) > 1 && !vis1[p] && !vis0[q]){
                    ans += (one.sz(p)-1) * (zero.sz(q)-1);
                    vis1[p] = true;
                    vis0[q] = true;
                }
            }
            pw.println(ans);
            pw.close();
        }
        class DSU{
             int N;
             int[] par, size;
             DSU(int N){
                this.N = N;
                par = new int[N]; size = new int[N];
                for(int i = 0; i < N; i++) {
                    par[i] = i;
                    size[i] = 1;
                }
            }
             int find(int x){ //wrong?
                if(x == par[x]){
                    return x;
                }
                return par[x] = find(par[x]);
            }
              void union(int x, int y){
                int p = find(x); int q = find(y);
                if(p != q){
                    if(size[p] < size[q]){
                        int temp = p;
                        p = q;
                        q = temp;
                    }
                    par[q] = p;
                    size[p] += size[q];

                }
            }
              int sz(int x){ return size[x];}
        }
    }

    //fastscanner class
    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(String s) {
            try {
                br = new BufferedReader(new FileReader(s));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }

}


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

/*
Solution Sketch:
*/

public class tree {

    static final boolean stdin = true;
    static final String filename = "";
    static FastScanner br;
    static PrintWriter pw;

    public static void main(String[] args) throws IOException {

        if (stdin) {
            br = new FastScanner();
            pw = new PrintWriter(new OutputStreamWriter(System.out));
        } else {
            br = new FastScanner(filename + ".in");
            pw = new PrintWriter(new FileWriter(filename + ".out"));
        }

        X solver = new X();
        solver.solve(br, pw);
    }

    static class X {
        public void solve(FastScanner br, PrintWriter pw) throws IOException {
            int N = br.nextInt();
            DSU zero = new DSU(N);
            DSU one = new DSU(N);
            for (int i = 0; i < N - 1; i++) {
                int x = br.nextInt(); int y = br.nextInt(); int c = br.nextInt();
                x--; y--;
                if (c == 0) {
                    zero.union(x, y);
                }
                else {
                    one.union(x, y);
                }
//                for(int j = 0; j < N; j++){
//                    pw.println(j + " " + zero.find(j) + " " + one.find(j));
//                }
//                pw.println();
            }

            long ans = 0;
            boolean[] vis0 = new boolean[N];
            boolean[] vis1 = new boolean[N];
            for(int i = 0; i < N; i++){ //deal with CC's of size 0 and 1
                if(!vis0[zero.find(i)]){
                    int p = zero.find(i);
                    if(zero.sz(p) > 1) {
//                        pw.println("zero: " + p + " " + zero.sz(p));
                        ans += (zero.sz(p) * (zero.sz(p)-1));
                    }
                    vis0[p] = true;
                }
                if(!vis1[one.find(i)]){
                    int p = one.find(i);
                    if(one.sz(p) > 1) {
//                        pw.println("one: " + p + " " + one.sz(p));
                        ans += (one.sz(p) * (one.sz(p)-1));
                    }
                    vis1[p] = true;
                }
                }
//            pw.println(ans);

            //deal with 0-1 case, for all CC of 1 multiply by number of other CC's (start at N then every merge --
            for(int i = 0; i < N; i++){
                int p = one.find(i); int q = zero.find(i);
                    ans += ((long)(one.sz(p)-1) * (long)(zero.sz(q)-1));
            }
            pw.println(ans);
            pw.close();
        }
        class DSU{
             int N;
             int[] par, size;
             DSU(int N){
                this.N = N;
                par = new int[N]; size = new int[N];
                for(int i = 0; i < N; i++) {
                    par[i] = i;
                    size[i] = 1;
                }
            }
             int find(int x){ //wrong?
                if(x == par[x]){
                    return x;
                }
                return par[x] = find(par[x]);
            }
              void union(int x, int y){
                int p = find(x); int q = find(y);
                if(p != q){
                    if(size[p] < size[q]){
                        int temp = p;
                        p = q;
                        q = temp;
                    }
                    par[q] = p;
                    size[p] += size[q];

                }
            }
              int sz(int x){ return size[x];}
        }
    }

    //fastscanner class
    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(String s) {
            try {
                br = new BufferedReader(new FileReader(s));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }

}


import java.util.*;
import java.io.*;
import static java.lang.Math.*;
import java.math.BigInteger;
public class Main {
    static final long MOD = 1_000_000_007 , INF = 1_000_000_000_000_000L;
    static final int INf = 1_000_000_000;
    static FastReader reader;
    static PrintWriter writer;
    public static void main(String[] args) {
        Thread t = new Thread(null, new O(), "Integer.MAX_VALUE", 100000000);
        t.start();
    }
    static class O implements Runnable {
        public void run() {
            try {
                magic();
            }
            catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
    }
    static class FastReader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public FastReader() {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public FastReader(String file_name) throws IOException {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException {
            byte[] buf = new byte[1000000];
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n') break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException {
            int ret = 0;
            byte c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (neg) return -ret;
            return ret;
        }

        public long nextLong() throws IOException {
            long ret = 0;
            byte c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (neg) return -ret;
            return ret;
        }

        public double nextDouble() throws IOException {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (c == '.') while ((c = read()) >= '0' && c <= '9') ret += (c - '0') / (div *= 10);
            if (neg) return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1) buffer[0] = -1;
        }

        private byte read() throws IOException {
            if (bufferPointer == bytesRead) fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException {
            if (din == null) return;
            din.close();
        }
    }
    static int n, dpInSubtree[][], dpOut[][];
    static ArrayList<Pair> adj[];
    static void magic() throws IOException {
        reader = new FastReader();
        writer = new PrintWriter(System.out, true);
        n = reader.nextInt();
        adj = new ArrayList[n+1];
        for(int i=1;i<=n;++i) {
            adj[i] = new ArrayList<>();
        }
        for(int i=1;i<n;++i) {
            int u = reader.nextInt(), v = reader.nextInt(), ty = reader.nextInt();
            adj[u].add(new Pair(v,ty));
            adj[v].add(new Pair(u, ty));
        }
        dpInSubtree = new int[n+1][2];
        dpOut = new int[n+1][2];
        dfs1(1,-1);
        dfs2(1,-1);
        long ans = 0;
        for(int i=1;i<=n;++i) {
            ans+=dpOut[i][0] + dpOut[i][1] + dpInSubtree[i][0] + dpInSubtree[i][1];
        }
        writer.println(ans);
    }
    static void dfs1(int x, int par) {
        for(Pair p : adj[x]) {
            if(p.x!=par) {
                dfs1(p.x, x);
                if(p.y==0) {
                    dpInSubtree[x][0] += dpInSubtree[p.x][0] + dpInSubtree[p.x][1]+1;
                }
                else {
                    dpInSubtree[x][1] += 1 + dpInSubtree[p.x][1];
                }
            }
        }
    }
    static void dfs2(int x, int par) {
        for(Pair p : adj[x]) {
            if(p.x==par) {
                if(p.y==0) {
                    dpOut[x][0] = 1 + dpOut[par][0] + dpOut[par][1] + dpInSubtree[par][0] + dpInSubtree[par][1] - dpInSubtree[x][0] - dpInSubtree[x][1] - 1;
                }
                else {
                    dpOut[x][1] = 1 + dpOut[par][1] + dpInSubtree[par][1] - dpInSubtree[x][1] - 1;
                }
            }
        }
        for(Pair p : adj[x]) {
            if(p.x!=par) {
                dfs2(p.x, x);
            }
        }
    }
    static class Pair implements Comparable<Pair>
    {
        int x,y;
        Pair(int x,int y)
        {
            this.x=x;
            this.y=y;
        }
        public int compareTo(Pair other)
        {
            if(this.x!=other.x)
                return this.x-other.x;
            return this.y-other.y;
        }
        public String toString()
        {
            return "("+x+","+y+")";
        }
    }
}


import java.util.*;
import java.io.*;
import static java.lang.Math.*;
import java.math.BigInteger;
public class Main {
    static final long MOD = 1_000_000_007 , INF = 1_000_000_000_000_000L;
    static final int INf = 1_000_000_000;
    static FastReader reader;
    static PrintWriter writer;
    public static void main(String[] args) {
        Thread t = new Thread(null, new O(), "Integer.MAX_VALUE", 100000000);
        t.start();
    }
    static class O implements Runnable {
        public void run() {
            try {
                magic();
            }
            catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
    }
    static class FastReader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public FastReader() {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public FastReader(String file_name) throws IOException {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException {
            byte[] buf = new byte[1000000];
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n') break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException {
            int ret = 0;
            byte c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (neg) return -ret;
            return ret;
        }

        public long nextLong() throws IOException {
            long ret = 0;
            byte c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (neg) return -ret;
            return ret;
        }

        public double nextDouble() throws IOException {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (c == '.') while ((c = read()) >= '0' && c <= '9') ret += (c - '0') / (div *= 10);
            if (neg) return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1) buffer[0] = -1;
        }

        private byte read() throws IOException {
            if (bufferPointer == bytesRead) fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException {
            if (din == null) return;
            din.close();
        }
    }
    static int n, dpInSubtree[][], dpOut[][];
    static ArrayList<Pair> adj[];
    static void magic() throws IOException {
        reader = new FastReader();
        writer = new PrintWriter(System.out, true);
        n = reader.nextInt();
        adj = new ArrayList[n+1];
        for(int i=1;i<=n;++i) {
            adj[i] = new ArrayList<>();
        }
        for(int i=1;i<n;++i) {
            int u = reader.nextInt(), v = reader.nextInt(), ty = reader.nextInt();
            adj[u].add(new Pair(v,ty));
            adj[v].add(new Pair(u, ty));
        }
        dpInSubtree = new int[n+1][2];
        dpOut = new int[n+1][2];
        dfs1(1,-1);
        dfs2(1,-1);
        long ans = 0;
        for(int i=1;i<=n;++i) {
            ans+=dpOut[i][0] + dpOut[i][1] + dpInSubtree[i][0] + dpInSubtree[i][1];
        }
        writer.println(ans);
    }
    static void dfs1(int x, int par) {
        for(Pair p : adj[x]) {
            if(p.x!=par) {
                dfs1(p.x, x);
                if(p.y==0) {
                    dpInSubtree[x][0] += dpInSubtree[p.x][0] + dpInSubtree[p.x][1]+1;
                }
                else {
                    dpInSubtree[x][1] += 1 + dpInSubtree[p.x][1];
                }
            }
        }
    }
    static void dfs2(int x, int par) {
        for(Pair p : adj[x]) {
            if(p.x==par) {
                if(p.y==0) {
                    dpOut[x][0] = 1 + dpOut[par][0] + dpOut[par][1] + dpInSubtree[par][0] + dpInSubtree[par][1] - dpInSubtree[x][0] - 1;
                }
                else {
                    dpOut[x][1] = 1 + dpOut[par][1] + dpInSubtree[par][1] - dpInSubtree[x][1] - 1;
                }
            }
        }
        for(Pair p : adj[x]) {
            if(p.x!=par) {
                dfs2(p.x, x);
            }
        }
    }
    static class Pair implements Comparable<Pair>
    {
        int x,y;
        Pair(int x,int y)
        {
            this.x=x;
            this.y=y;
        }
        public int compareTo(Pair other)
        {
            if(this.x!=other.x)
                return this.x-other.x;
            return this.y-other.y;
        }
        public String toString()
        {
            return "("+x+","+y+")";
        }
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.Collection;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.Queue;
import java.util.LinkedList;
import java.io.InputStream;

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

    static class D01Tree {
        ArrayList<Integer> al = new ArrayList<>();
        ArrayList<Pair>[] adj;
        Queue<Integer> q = new LinkedList<>();
        boolean[] vis;

        int bfs(int s, int y) {
            int ct = 0, x;
            q.add(s);
            al.add(s);
            vis[s] = true;
            while (!q.isEmpty()) {
                x = q.poll();
                for (Pair p : adj[x]) {
                    if (p.y == y && !vis[p.x]) {
                        ct++;
                        vis[p.x] = true;
                        q.add(p.x);
                        al.add(p.x);
                    }
                }
            }
            return ct;
        }

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int n = in.nextInt(), x, y, z;
            adj = new ArrayList[n + 1];
            for (int i = 1; i <= n; i++)
                adj[i] = new ArrayList<>();
            long[] a = new long[n + 1];
            vis = new boolean[n + 1];
            for (int i = 1; i < n; i++) {
                x = in.nextInt();
                y = in.nextInt();
                z = in.nextInt();
                adj[x].add(new Pair(y, z));
                adj[y].add(new Pair(x, z));
            }
            long sum;
            for (int i = 1; i >= 0; i--) {
                for (int j = 1; j <= n; j++) {
                    if (!vis[j]) {
                        al.clear();
                        sum = 0;
                        x = bfs(j, i);
                        for (int k : al)
                            sum += a[k];
                        sum += x;
                        for (int k : al)
                            a[k] += (sum - a[k]);
                    }
                }
                Arrays.fill(vis, false);
            }
            sum = 0;
            for (int i = 1; i <= n; i++)
                sum += a[i];
            out.println(sum);
        }

    }

    static class Pair implements Comparable<Pair> {
        public int x;
        public int y;

        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair pair = (Pair) o;
            return x == pair.x &&
                    y == pair.y;
        }

        public int hashCode() {
            return Objects.hash(x, y);
        }

        public int compareTo(Pair p) {
            return Integer.compare(x, p.x);
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void println(Object... objects) {
            print(objects);
            writer.println();
        }

        public void close() {
            writer.close();
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[8192];
        private int curChar;
        private int snumChars;
        private InputReader.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 boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.Collection;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.Queue;
import java.util.LinkedList;
import java.io.InputStream;

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

    static class D01Tree {
        ArrayList<Integer> al = new ArrayList<>();
        ArrayList<Pair>[] adj;
        Queue<Integer> q = new LinkedList<>();
        boolean[] vis;

        int bfs(int s, int y) {
            int ct = 0, x;
            q.add(s);
            al.add(s);
            vis[s] = true;
            while (!q.isEmpty()) {
                x = q.poll();
                for (Pair p : adj[x]) {
                    if (p.y == y && !vis[p.x]) {
                        ct++;
                        vis[p.x] = true;
                        q.add(p.x);
                        al.add(p.x);
                    }
                }
            }
            return ct;
        }

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int n = in.nextInt(), x, y, z;
            adj = new ArrayList[n + 1];
            for (int i = 1; i <= n; i++)
                adj[i] = new ArrayList<>();
            int[] a = new int[n + 1];
            vis = new boolean[n + 1];
            for (int i = 1; i < n; i++) {
                x = in.nextInt();
                y = in.nextInt();
                z = in.nextInt();
                adj[x].add(new Pair(y, z));
                adj[y].add(new Pair(x, z));
            }
            for (int i = 1; i >= 0; i--) {
                for (int j = 1; j <= n; j++) {
                    if (!vis[j]) {
                        al.clear();
                        y = 0;
                        x = bfs(j, i);
                        for (int k : al)
                            y += a[k];
                        y += x;
                        for (int k : al)
                            a[k] += (y - a[k]);
                    }
                }
                Arrays.fill(vis, false);
            }
            x = 0;
            for (int i = 1; i <= n; i++)
                x += a[i];
            out.println(x);
        }

    }

    static class Pair implements Comparable<Pair> {
        public int x;
        public int y;

        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair pair = (Pair) o;
            return x == pair.x &&
                    y == pair.y;
        }

        public int hashCode() {
            return Objects.hash(x, y);
        }

        public int compareTo(Pair p) {
            return Integer.compare(x, p.x);
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void println(Object... objects) {
            print(objects);
            writer.println();
        }

        public void close() {
            writer.close();
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[8192];
        private int curChar;
        private int snumChars;
        private InputReader.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 boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


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

@SuppressWarnings("unchecked")
public class CF1156D {
	class DSU {
		int[] p, size;
		public DSU(int n) {
			p = new int[n];
			for(int i = 0 ; i < n ; i++) p[i] = i;
			size = new int[n];
			Arrays.fill(size, 1);
		}
		int find(int x) { return x == p[x] ? x : (p[x] = find(p[x])); }
		boolean union(int u, int v) {
			int p1 = find(u), p2 = find(v);
			if(p1 != p2) {
				p[p1] = p2;
				size[p2] += size[p1];
				return true;
			}
			return false;
		}
	}
	// 0 -> 0 -> 1 -> 1 this is okay
	// 1 -> 0 this is not okay
	public CF1156D() {
		FS scan = new FS();
		int n = scan.nextInt();
		DSU[] dsu = new DSU[] {new DSU(n), new DSU(n)};
		for(int i = 0 ; i < n - 1 ; i++) {
			int u = scan.nextInt() - 1, v = scan.nextInt() - 1, c = scan.nextInt();
			dsu[c].union(u, v);
		}
		boolean[] visited = new boolean[n];
		long res = 0;
		for(int i = 0 ; i < n ; i++) {
			long size0 = dsu[0].size[dsu[0].find(i)];
			long size1 = dsu[1].size[dsu[1].find(i)];
			res += size0 * size1 - 1;
		}
		System.out.println(res);
	}
	int abs(int x) { return max(x, -x); }
	int min(int a, int b) { return a < b ? a : b; }
	int max(int a, int b) { return a > b ? a : b; }
	class FS {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");
		public String next() {
			while(!st.hasMoreTokens()) {
				try { st = new StringTokenizer(br.readLine()); }
				catch(Exception e) { e.printStackTrace(); }
			}
			return st.nextToken();
		}
		public int nextInt() { return Integer.parseInt(next()); }
	}
	public static void main(String[] args) { new CF1156D(); }
}


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.*;

public class CFCR1156 {
    public static void main(String[] args) throws Exception {
        boolean local = System.getProperty("ONLINE_JUDGE") == null;
        boolean async = false;

        Charset charset = Charset.forName("ascii");

        FastIO io = local ? new FastIO(new FileInputStream("D:\\DATABASE\\TESTCASE\\Code.in"), System.out, charset) : new FastIO(System.in, System.out, charset);
        Task task = new Task(io, new Debug(local));

        if (async) {
            Thread t = new Thread(null, task, "dalt", 1 << 27);
            t.setPriority(Thread.MAX_PRIORITY);
            t.start();
            t.join();
        } else {
            task.run();
        }

        if (local) {
            io.cache.append("\n\n--memory -- \n" + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20) + "M");
        }

        io.flush();
    }

    public static class Task implements Runnable {
        final FastIO io;
        final Debug debug;
        int inf = (int) 1e8;
        int mod = (int) 1e9 + 7;

        public int mod(int val) {
            val %= mod;
            if (val < 0) {
                val += mod;
            }
            return val;
        }

        public int mod(long val) {
            val %= mod;
            if (val < 0) {
                val += mod;
            }
            return (int) val;
        }

        public Task(FastIO io, Debug debug) {
            this.io = io;
            this.debug = debug;
        }

        @Override
        public void run() {
            solve();
        }

        public void solve() {
            int n = io.readInt();
            Node[] nodes = new Node[n + 1];
            for (int i = 1; i <= n; i++) {
                nodes[i] = new Node();
            }

            for (int i = 1; i < n; i++) {
                Edge edge = new Edge();
                edge.a = nodes[io.readInt()];
                edge.b = nodes[io.readInt()];
                edge.c = io.readInt();
                edge.a.edges.add(edge);
                edge.b.edges.add(edge);
            }

            dfs(nodes[1], null);
            long sum = 0;
            for (int i = 1; i <= n; i++) {
                sum += nodes[i].cnt;
            }
            io.cache.append(sum);
        }

        static void dfs(Node root, Edge from) {

            for (Edge edge : root.edges) {
                if (edge == from) {
                    continue;
                }
                Node node = edge.another(root);
                dfs(node, edge);

                int[] tmpDp = new int[4];
                if (edge.c == 0) {
                    tmpDp[2] = node.dp[2] + node.dp[3];
                    tmpDp[0] = node.dp[0] + 1;
                } else {
                    tmpDp[3] = node.dp[3] + 1;
                    tmpDp[1] = node.dp[0] + node.dp[1];
                }

                root.cnt += (root.dp[2] + root.dp[3] + root.dp[0]) * tmpDp[0]; // -> 00
                root.cnt += (tmpDp[2] + tmpDp[3] + tmpDp[0]) * root.dp[0];
                root.cnt += (root.dp[3]) * tmpDp[2];// -> 10
                root.cnt += (tmpDp[3]) * root.dp[2];
                root.cnt += (root.dp[3]) * tmpDp[3];// -> 11
                root.cnt += (tmpDp[3]) * root.dp[3];// -> 11

                for (int i = 0; i < 4; i++) {
                    root.dp[i] += tmpDp[i];
                }
            }

            root.cnt += root.dp[0] * 2 + root.dp[1] + root.dp[2] + root.dp[3] * 2;
        }
    }

    public static class Node {
        List<Edge> edges = new ArrayList<>();
        int[] dp = new int[4];
        long cnt;
    }

    public static class Edge {
        Node a;
        Node b;
        int c;

        Node another(Node me) {
            return a == me ? b : a;
        }
    }

    public static class Randomized {
        static Random random = new Random(123456789);

        public static double nextDouble(double min, double max) {
            return random.nextDouble() * (max - min) + min;
        }

        public static void randomizedArray(int[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                int tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static void randomizedArray(long[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                long tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static void randomizedArray(double[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                double tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static void randomizedArray(float[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                float tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static <T> void randomizedArray(T[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                T tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static int nextInt(int l, int r) {
            return random.nextInt(r - l + 1) + l;
        }
    }

    public static class Mathematics {

        public static int ceilPowerOf2(int x) {
            return 32 - Integer.numberOfLeadingZeros(x - 1);
        }

        public static int floorPowerOf2(int x) {
            return 31 - Integer.numberOfLeadingZeros(x);
        }

        public static long modmul(long a, long b, long mod) {
            return b == 0 ? 0 : ((modmul(a, b >> 1, mod) << 1) % mod + a * (b & 1)) % mod;
        }

        /**
         * Get the greatest common divisor of a and b
         */
        public static int gcd(int a, int b) {
            return a >= b ? gcd0(a, b) : gcd0(b, a);
        }

        private static int gcd0(int a, int b) {
            return b == 0 ? a : gcd0(b, a % b);
        }

        public static int extgcd(int a, int b, int[] coe) {
            if (a >= b) {
                return extgcd0(a, b, coe);
            } else {
                int g = extgcd0(b, a, coe);
                int tmp = coe[0];
                coe[0] = coe[1];
                coe[1] = tmp;
                return g;
            }
        }

        private static int extgcd0(int a, int b, int[] coe) {
            if (b == 0) {
                coe[0] = 1;
                coe[1] = 0;
                return a;
            }
            int g = extgcd0(b, a % b, coe);
            int n = coe[0];
            int m = coe[1];
            coe[0] = m;
            coe[1] = n - m * (a / b);
            return g;
        }

        /**
         * Get the greatest common divisor of a and b
         */
        public static long gcd(long a, long b) {
            return a >= b ? gcd0(a, b) : gcd0(b, a);
        }

        private static long gcd0(long a, long b) {
            return b == 0 ? a : gcd0(b, a % b);
        }

        public static long extgcd(long a, long b, long[] coe) {
            if (a >= b) {
                return extgcd0(a, b, coe);
            } else {
                long g = extgcd0(b, a, coe);
                long tmp = coe[0];
                coe[0] = coe[1];
                coe[1] = tmp;
                return g;
            }
        }

        private static long extgcd0(long a, long b, long[] coe) {
            if (b == 0) {
                coe[0] = 1;
                coe[1] = 0;
                return a;
            }
            long g = extgcd0(b, a % b, coe);
            long n = coe[0];
            long m = coe[1];
            coe[0] = m;
            coe[1] = n - m * (a / b);
            return g;
        }

        /**
         * Get y where x * y = 1 (% mod)
         */
        public static int inverse(int x, int mod) {
            return pow(x, mod - 2, mod);
        }

        /**
         * Get x^n(% mod)
         */
        public static int pow(int x, int n, int mod) {
            int bit = 31 - Integer.numberOfLeadingZeros(n);
            long product = 1;
            for (; bit >= 0; bit--) {
                product = product * product % mod;
                if (((1 << bit) & n) != 0) {
                    product = product * x % mod;
                }
            }
            return (int) product;
        }

        public static long longpow(long x, long n, long mod) {
            if (n == 0) {
                return 1;
            }
            long prod = longpow(x, n >> 1, mod);
            prod = modmul(prod, prod, mod);
            if ((n & 1) == 1) {
                prod = modmul(prod, x, mod);
            }
            return prod;
        }

        /**
         * Get x % mod
         */
        public static int mod(int x, int mod) {
            x %= mod;
            if (x < 0) {
                x += mod;
            }
            return x;
        }

        public static int mod(long x, int mod) {
            x %= mod;
            if (x < 0) {
                x += mod;
            }
            return (int) x;
        }

        /**
         * Get n!/(n-m)!
         */
        public static long permute(int n, int m) {
            return m == 0 ? 1 : n * permute(n - 1, m - 1);
        }

        /**
         * Put all primes less or equal to limit into primes after offset
         */
        public static int eulerSieve(int limit, int[] primes, int offset) {
            boolean[] isComp = new boolean[limit + 1];
            int wpos = offset;
            for (int i = 2; i <= limit; i++) {
                if (!isComp[i]) {
                    primes[wpos++] = i;
                }
                for (int j = offset, until = limit / i; j < wpos && primes[j] <= until; j++) {
                    int pi = primes[j] * i;
                    isComp[pi] = true;
                    if (i % primes[j] == 0) {
                        break;
                    }
                }
            }
            return wpos - offset;
        }

        /**
         * Round x into integer
         */
        public static int intRound(double x) {
            if (x < 0) {
                return -(int) (-x + 0.5);
            }
            return (int) (x + 0.5);
        }

        /**
         * Round x into long
         */
        public static long longRound(double x) {
            if (x < 0) {
                return -(long) (-x + 0.5);
            }
            return (long) (x + 0.5);
        }
    }

    public static class FastIO {
        public final StringBuilder cache = new StringBuilder();
        private final InputStream is;
        private final OutputStream os;
        private final Charset charset;
        private StringBuilder defaultStringBuf = new StringBuilder(1 << 8);
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastIO(InputStream is, OutputStream os, Charset charset) {
            this.is = is;
            this.os = os;
            this.charset = charset;
        }

        public FastIO(InputStream is, OutputStream os) {
            this(is, os, Charset.forName("ascii"));
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

        public long readLong() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            long val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

        public double readDouble() {
            boolean sign = true;
            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+';
                next = read();
            }

            long val = 0;
            while (next >= '0' && next <= '9') {
                val = val * 10 + next - '0';
                next = read();
            }
            if (next != '.') {
                return sign ? val : -val;
            }
            next = read();
            long radix = 1;
            long point = 0;
            while (next >= '0' && next <= '9') {
                point = point * 10 + next - '0';
                radix = radix * 10;
                next = read();
            }
            double result = val + (double) point / radix;
            return sign ? result : -result;
        }

        public String readString(StringBuilder builder) {
            skipBlank();

            while (next > 32) {
                builder.append((char) next);
                next = read();
            }

            return builder.toString();
        }

        public String readString() {
            defaultStringBuf.setLength(0);
            return readString(defaultStringBuf);
        }

        public int readLine(char[] data, int offset) {
            int originalOffset = offset;
            while (next != -1 && next != '\n') {
                data[offset++] = (char) next;
                next = read();
            }
            return offset - originalOffset;
        }

        public int readString(char[] data, int offset) {
            skipBlank();

            int originalOffset = offset;
            while (next > 32) {
                data[offset++] = (char) next;
                next = read();
            }

            return offset - originalOffset;
        }

        public int readString(byte[] data, int offset) {
            skipBlank();

            int originalOffset = offset;
            while (next > 32) {
                data[offset++] = (byte) next;
                next = read();
            }

            return offset - originalOffset;
        }

        public char readChar() {
            skipBlank();
            char c = (char) next;
            next = read();
            return c;
        }

        public void flush() {
            try {
                os.write(cache.toString().getBytes(charset));
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public boolean hasMore() {
            skipBlank();
            return next != -1;
        }
    }

    public static class Debug {
        private boolean allowDebug;

        public Debug(boolean allowDebug) {
            this.allowDebug = allowDebug;
        }

        public void assertTrue(boolean flag) {
            if (!allowDebug) {
                return;
            }
            if (!flag) {
                fail();
            }
        }

        public void fail() {
            throw new RuntimeException();
        }

        public void assertFalse(boolean flag) {
            if (!allowDebug) {
                return;
            }
            if (flag) {
                fail();
            }
        }

        private void outputName(String name) {
            System.out.print(name + " = ");
        }

        public void debug(String name, int x) {
            if (!allowDebug) {
                return;
            }

            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, long x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, double x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, int[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, long[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, double[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, Object x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, Object... x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.deepToString(x));
        }
    }
}


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.*;

public class CFCR1156 {
    public static void main(String[] args) throws Exception {
        boolean local = System.getProperty("ONLINE_JUDGE") == null;
        boolean async = false;

        Charset charset = Charset.forName("ascii");

        FastIO io = local ? new FastIO(new FileInputStream("D:\\DATABASE\\TESTCASE\\Code.in"), System.out, charset) : new FastIO(System.in, System.out, charset);
        Task task = new Task(io, new Debug(local));

        if (async) {
            Thread t = new Thread(null, task, "dalt", 1 << 27);
            t.setPriority(Thread.MAX_PRIORITY);
            t.start();
            t.join();
        } else {
            task.run();
        }

        if (local) {
            io.cache.append("\n\n--memory -- \n" + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20) + "M");
        }

        io.flush();
    }

    public static class Task implements Runnable {
        final FastIO io;
        final Debug debug;
        int inf = (int) 1e8;
        int mod = (int) 1e9 + 7;

        public int mod(int val) {
            val %= mod;
            if (val < 0) {
                val += mod;
            }
            return val;
        }

        public int mod(long val) {
            val %= mod;
            if (val < 0) {
                val += mod;
            }
            return (int) val;
        }

        public Task(FastIO io, Debug debug) {
            this.io = io;
            this.debug = debug;
        }

        @Override
        public void run() {
            solve();
        }

        public void solve() {
            int n = io.readInt();
            Node[] nodes = new Node[n + 1];
            for (int i = 1; i <= n; i++) {
                nodes[i] = new Node();
            }

            for (int i = 1; i < n; i++) {
                Edge edge = new Edge();
                edge.a = nodes[io.readInt()];
                edge.b = nodes[io.readInt()];
                edge.c = io.readInt();
                edge.a.edges.add(edge);
                edge.b.edges.add(edge);
            }

            dfs(nodes[1], null);
            long sum = 0;
            for (int i = 1; i <= n; i++) {
                sum += nodes[i].cnt;
            }
            io.cache.append(sum);
        }

        static void dfs(Node root, Edge from) {

            for (Edge edge : root.edges) {
                if (edge == from) {
                    continue;
                }
                Node node = edge.another(root);
                dfs(node, edge);

                long[] tmpDp = new long[4];
                if (edge.c == 0) {
                    tmpDp[2] = node.dp[2] + node.dp[3];
                    tmpDp[0] = node.dp[0] + 1;
                } else {
                    tmpDp[3] = node.dp[3] + 1;
                    tmpDp[1] = node.dp[0] + node.dp[1];
                }

                root.cnt += (root.dp[2] + root.dp[3] + root.dp[0]) * tmpDp[0]; // -> 00
                root.cnt += (tmpDp[2] + tmpDp[3] + tmpDp[0]) * root.dp[0];
                root.cnt += (root.dp[3]) * tmpDp[2];// -> 10
                root.cnt += (tmpDp[3]) * root.dp[2];
                root.cnt += (root.dp[3]) * tmpDp[3];// -> 11
                root.cnt += (tmpDp[3]) * root.dp[3];// -> 11

                for (int i = 0; i < 4; i++) {
                    root.dp[i] += tmpDp[i];
                }
            }

            root.cnt += root.dp[0] * 2 + root.dp[1] + root.dp[2] + root.dp[3] * 2;
        }
    }

    public static class Node {
        List<Edge> edges = new ArrayList<>();
        long[] dp = new long[4];
        long cnt;
    }

    public static class Edge {
        Node a;
        Node b;
        int c;

        Node another(Node me) {
            return a == me ? b : a;
        }
    }

    public static class Randomized {
        static Random random = new Random(123456789);

        public static double nextDouble(double min, double max) {
            return random.nextDouble() * (max - min) + min;
        }

        public static void randomizedArray(int[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                int tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static void randomizedArray(long[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                long tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static void randomizedArray(double[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                double tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static void randomizedArray(float[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                float tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static <T> void randomizedArray(T[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                T tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static int nextInt(int l, int r) {
            return random.nextInt(r - l + 1) + l;
        }
    }

    public static class Mathematics {

        public static int ceilPowerOf2(int x) {
            return 32 - Integer.numberOfLeadingZeros(x - 1);
        }

        public static int floorPowerOf2(int x) {
            return 31 - Integer.numberOfLeadingZeros(x);
        }

        public static long modmul(long a, long b, long mod) {
            return b == 0 ? 0 : ((modmul(a, b >> 1, mod) << 1) % mod + a * (b & 1)) % mod;
        }

        /**
         * Get the greatest common divisor of a and b
         */
        public static int gcd(int a, int b) {
            return a >= b ? gcd0(a, b) : gcd0(b, a);
        }

        private static int gcd0(int a, int b) {
            return b == 0 ? a : gcd0(b, a % b);
        }

        public static int extgcd(int a, int b, int[] coe) {
            if (a >= b) {
                return extgcd0(a, b, coe);
            } else {
                int g = extgcd0(b, a, coe);
                int tmp = coe[0];
                coe[0] = coe[1];
                coe[1] = tmp;
                return g;
            }
        }

        private static int extgcd0(int a, int b, int[] coe) {
            if (b == 0) {
                coe[0] = 1;
                coe[1] = 0;
                return a;
            }
            int g = extgcd0(b, a % b, coe);
            int n = coe[0];
            int m = coe[1];
            coe[0] = m;
            coe[1] = n - m * (a / b);
            return g;
        }

        /**
         * Get the greatest common divisor of a and b
         */
        public static long gcd(long a, long b) {
            return a >= b ? gcd0(a, b) : gcd0(b, a);
        }

        private static long gcd0(long a, long b) {
            return b == 0 ? a : gcd0(b, a % b);
        }

        public static long extgcd(long a, long b, long[] coe) {
            if (a >= b) {
                return extgcd0(a, b, coe);
            } else {
                long g = extgcd0(b, a, coe);
                long tmp = coe[0];
                coe[0] = coe[1];
                coe[1] = tmp;
                return g;
            }
        }

        private static long extgcd0(long a, long b, long[] coe) {
            if (b == 0) {
                coe[0] = 1;
                coe[1] = 0;
                return a;
            }
            long g = extgcd0(b, a % b, coe);
            long n = coe[0];
            long m = coe[1];
            coe[0] = m;
            coe[1] = n - m * (a / b);
            return g;
        }

        /**
         * Get y where x * y = 1 (% mod)
         */
        public static int inverse(int x, int mod) {
            return pow(x, mod - 2, mod);
        }

        /**
         * Get x^n(% mod)
         */
        public static int pow(int x, int n, int mod) {
            int bit = 31 - Integer.numberOfLeadingZeros(n);
            long product = 1;
            for (; bit >= 0; bit--) {
                product = product * product % mod;
                if (((1 << bit) & n) != 0) {
                    product = product * x % mod;
                }
            }
            return (int) product;
        }

        public static long longpow(long x, long n, long mod) {
            if (n == 0) {
                return 1;
            }
            long prod = longpow(x, n >> 1, mod);
            prod = modmul(prod, prod, mod);
            if ((n & 1) == 1) {
                prod = modmul(prod, x, mod);
            }
            return prod;
        }

        /**
         * Get x % mod
         */
        public static int mod(int x, int mod) {
            x %= mod;
            if (x < 0) {
                x += mod;
            }
            return x;
        }

        public static int mod(long x, int mod) {
            x %= mod;
            if (x < 0) {
                x += mod;
            }
            return (int) x;
        }

        /**
         * Get n!/(n-m)!
         */
        public static long permute(int n, int m) {
            return m == 0 ? 1 : n * permute(n - 1, m - 1);
        }

        /**
         * Put all primes less or equal to limit into primes after offset
         */
        public static int eulerSieve(int limit, int[] primes, int offset) {
            boolean[] isComp = new boolean[limit + 1];
            int wpos = offset;
            for (int i = 2; i <= limit; i++) {
                if (!isComp[i]) {
                    primes[wpos++] = i;
                }
                for (int j = offset, until = limit / i; j < wpos && primes[j] <= until; j++) {
                    int pi = primes[j] * i;
                    isComp[pi] = true;
                    if (i % primes[j] == 0) {
                        break;
                    }
                }
            }
            return wpos - offset;
        }

        /**
         * Round x into integer
         */
        public static int intRound(double x) {
            if (x < 0) {
                return -(int) (-x + 0.5);
            }
            return (int) (x + 0.5);
        }

        /**
         * Round x into long
         */
        public static long longRound(double x) {
            if (x < 0) {
                return -(long) (-x + 0.5);
            }
            return (long) (x + 0.5);
        }
    }

    public static class FastIO {
        public final StringBuilder cache = new StringBuilder();
        private final InputStream is;
        private final OutputStream os;
        private final Charset charset;
        private StringBuilder defaultStringBuf = new StringBuilder(1 << 8);
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastIO(InputStream is, OutputStream os, Charset charset) {
            this.is = is;
            this.os = os;
            this.charset = charset;
        }

        public FastIO(InputStream is, OutputStream os) {
            this(is, os, Charset.forName("ascii"));
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

        public long readLong() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            long val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

        public double readDouble() {
            boolean sign = true;
            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+';
                next = read();
            }

            long val = 0;
            while (next >= '0' && next <= '9') {
                val = val * 10 + next - '0';
                next = read();
            }
            if (next != '.') {
                return sign ? val : -val;
            }
            next = read();
            long radix = 1;
            long point = 0;
            while (next >= '0' && next <= '9') {
                point = point * 10 + next - '0';
                radix = radix * 10;
                next = read();
            }
            double result = val + (double) point / radix;
            return sign ? result : -result;
        }

        public String readString(StringBuilder builder) {
            skipBlank();

            while (next > 32) {
                builder.append((char) next);
                next = read();
            }

            return builder.toString();
        }

        public String readString() {
            defaultStringBuf.setLength(0);
            return readString(defaultStringBuf);
        }

        public int readLine(char[] data, int offset) {
            int originalOffset = offset;
            while (next != -1 && next != '\n') {
                data[offset++] = (char) next;
                next = read();
            }
            return offset - originalOffset;
        }

        public int readString(char[] data, int offset) {
            skipBlank();

            int originalOffset = offset;
            while (next > 32) {
                data[offset++] = (char) next;
                next = read();
            }

            return offset - originalOffset;
        }

        public int readString(byte[] data, int offset) {
            skipBlank();

            int originalOffset = offset;
            while (next > 32) {
                data[offset++] = (byte) next;
                next = read();
            }

            return offset - originalOffset;
        }

        public char readChar() {
            skipBlank();
            char c = (char) next;
            next = read();
            return c;
        }

        public void flush() {
            try {
                os.write(cache.toString().getBytes(charset));
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public boolean hasMore() {
            skipBlank();
            return next != -1;
        }
    }

    public static class Debug {
        private boolean allowDebug;

        public Debug(boolean allowDebug) {
            this.allowDebug = allowDebug;
        }

        public void assertTrue(boolean flag) {
            if (!allowDebug) {
                return;
            }
            if (!flag) {
                fail();
            }
        }

        public void fail() {
            throw new RuntimeException();
        }

        public void assertFalse(boolean flag) {
            if (!allowDebug) {
                return;
            }
            if (flag) {
                fail();
            }
        }

        private void outputName(String name) {
            System.out.print(name + " = ");
        }

        public void debug(String name, int x) {
            if (!allowDebug) {
                return;
            }

            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, long x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, double x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, int[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, long[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, double[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, Object x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, Object... x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.deepToString(x));
        }
    }
}