/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x1156D
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         LinkedList<Edge>[] edges = new LinkedList[N+1];
         for(int i=1; i <= N; i++)
            edges[i] = new LinkedList<Edge>();
         for(int i=1; i < N; i++)
         {
            st = new StringTokenizer(infile.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));
         }
         int root = 1;
         long[][] dp = new long[N+1][2];
         dfs(root, dp, new boolean[N+1], edges);
         //dp[i][0] = # of children to i paths that end with 0
         //dp[i][1] = # of children to i paths containing 1

         long[][] dp2 = new long[N+1][2];
         //dp2[i][0/1] = # of paths ending at i
         reroot(root, dp2, new boolean[N+1], edges, dp);
         long res = 0L;
         for(int i=1; i <= N; i++)
            res += dp2[i][0]+dp2[i][1];

         System.out.println(res);
      }
      public static void reroot(int curr, long[][] dp, boolean[] seen, LinkedList<Edge>[] edges, long[][] dp_subtree)
      {
         seen[curr] = true;
         dp[curr][0] += dp_subtree[curr][0];
         dp[curr][1] += dp_subtree[curr][1];
         for(Edge e: edges[curr])
         {
            int next = e.to;
            if(seen[next])
               continue;
            if(e.color == 0)
            {
               long prev = dp[curr][0];
               if(dp_subtree[next][0] == 0)
                  prev--;
               else
                  prev -= dp_subtree[next][0];
               dp[next][0] += 1+prev;
            }
            else
            {
               long prev = dp[curr][1]+dp[curr][0];
               prev -= dp_subtree[next][0]+dp_subtree[next][1];
               dp[next][1] += prev;
            }
            reroot(next, dp, seen, edges, dp_subtree);
         }
      }
      public static void dfs(int curr, long[][] dp, boolean[] seen, LinkedList<Edge>[] edges)
      {
         seen[curr] = true;
         long res0 = 0L;
         long res1 = 0L;
         for(Edge e: edges[curr])
         {
            int next = e.to;
            if(seen[next])
               continue;
            dfs(next, dp, seen, edges);
            if(e.color == 0)
               res0 += 1+dp[next][0];
            else
               res1 += 1+dp[next][0]+dp[next][1];
         }
         dp[curr][0] += res0;
         dp[curr][1] += res1;
      }
   }
   class Edge
   {
      public int to;
      public int color;

      public Edge(int a, int b)
      {
         to = a;
         color = b;
      }
   }


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x1156D
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         LinkedList<Edge>[] edges = new LinkedList[N+1];
         for(int i=1; i <= N; i++)
            edges[i] = new LinkedList<Edge>();
         for(int i=1; i < N; i++)
         {
            st = new StringTokenizer(infile.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));
         }
         int root = 1;
         long[][] dp = new long[N+1][2];
         dfs(root, dp, new boolean[N+1], edges);
         //dp[i][0] = # of children to i paths that end with 0
         //dp[i][1] = # of children to i paths containing 1

         long[][] dp2 = new long[N+1][2];
         //dp2[i][0/1] = # of paths ending at i
         reroot(root, dp2, new boolean[N+1], edges, dp);
         long res = 0L;
         for(int i=1; i <= N; i++)
            res += dp2[i][0]+dp2[i][1];

         System.out.println(res);
      }
      public static void reroot(int curr, long[][] dp, boolean[] seen, LinkedList<Edge>[] edges, long[][] dp_subtree)
      {
         seen[curr] = true;
         dp[curr][0] += dp_subtree[curr][0];
         dp[curr][1] += dp_subtree[curr][1];
         for(Edge e: edges[curr])
         {
            int next = e.to;
            if(seen[next])
               continue;
            if(e.color == 0)
            {
               long prev = dp[curr][0];
               prev -= dp_subtree[next][0];
               dp[next][0] += prev;
            }
            else
            {
               long prev = dp[curr][1]+dp[curr][0];
               prev -= dp_subtree[next][0]+dp_subtree[next][1];
               dp[next][1] += prev;
            }
            reroot(next, dp, seen, edges, dp_subtree);
         }
      }
      public static void dfs(int curr, long[][] dp, boolean[] seen, LinkedList<Edge>[] edges)
      {
         seen[curr] = true;
         long res0 = 0L;
         long res1 = 0L;
         for(Edge e: edges[curr])
         {
            int next = e.to;
            if(seen[next])
               continue;
            dfs(next, dp, seen, edges);
            if(e.color == 0)
               res0 += 1+dp[next][0];
            else
               res1 += 1+dp[next][0]+dp[next][1];
         }
         dp[curr][0] += res0;
         dp[curr][1] += res1;
      }
   }
   class Edge
   {
      public int to;
      public int color;

      public Edge(int a, int b)
      {
         to = a;
         color = b;
      }
   }


import java.util.*;
import java.io.*;
public class ZeroOneTree {
	public static int[][] father;
	public static int[][] size;

	public static int find(int c, int x) {
		 while (father[c][x] != x) {
			 x = father[c][x];
		 }
		 return x;
	}

	public static void union(int c, int x, int y) {
		int fcx = find(c, x);
		int fcy = find(c, y);
		if (fcx == fcy) return;
		father[c][fcy] = fcx;
		size[c][fcx] += size[c][fcy];
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		father = new int[2][n + 1];
		size = new int[2][n + 1];
		for (int i = 1; i <= n; i++) {
			father[0][i] = i;
			father[1][i] = i;
			size[0][i] = 1;
			size[1][i] = 1;
		}
		for (int i = 0; i < n - 1; i++) {
			int x = sc.nextInt();
			int y = sc.nextInt();
			int c = sc.nextInt();
			union(c, x, y);
		}

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


import java.util.*;
import java.io.*;
public class ZeroOneTree {
	public static int[][] father;
	public static int[][] size;

	public static int find(int c, int x) {
		 while (father[c][x] != x) {
			 father[c][x] = father[c][father[c][x]];
			 x = father[c][x];
		 }
		 return x;
	}

	public static void union(int c, int x, int y) {
		int fcx = find(c, x);
		int fcy = find(c, y);
		if (fcx == fcy) return;
		if (size[c][fcx] > size[c][fcy]) {
			father[c][fcy] = fcx;
			size[c][fcx] += size[c][fcy];
		} else {
			father[c][fcx] = fcy;
			size[c][fcy] += size[c][fcx];
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		father = new int[2][n + 1];
		size = new int[2][n + 1];
		for (int i = 1; i <= n; i++) {
			father[0][i] = i;
			father[1][i] = i;
			size[0][i] = 1;
			size[1][i] = 1;
		}
		for (int i = 0; i < n - 1; i++) {
			int x = sc.nextInt();
			int y = sc.nextInt();
			int c = sc.nextInt();
			union(c, x, y);
		}

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


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

/**
 * @author khokharnikunj8
 */

public class Main {
    public static void main(String[] args) {
        new Thread(null, new Runnable() {
            public void run() {
                new Main().solve();
            }
        }, "1", 1 << 26).start();
    }

    void solve() {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        D01Tree solver = new D01Tree();
        solver.solve(1, in, out);
        out.close();
    }

    static class D01Tree {
        int[][][] G;
        long[][] dp;
        long ans;

        public void findIt(int n, int p) {
            for (int[] i : G[n]) {
                if (i[0] == p) continue;
                findIt(i[0], n);
                if (i[1] == 1) {
                    dp[n][1] += dp[i[0]][1] + 1;
                    dp[n][3] += (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] += dp[i[0]][0] + 1;
                    dp[n][2] += (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }
            }
            ans += (dp[n][0] * 2l);
            ans += (dp[n][1] * 2l);
            ans += dp[n][2] - dp[n][0];
            ans += dp[n][3] - dp[n][1];
            for (int[] i : G[n]) {
                if (i[0] == p) continue;
                if (i[1] == 1) {
                    dp[n][1] -= dp[i[0]][1] + 1;
                    dp[n][3] -= (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] -= dp[i[0]][0] + 1;
                    dp[n][2] -= (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }
                if (i[1] == 0) {
                    ans += ((dp[i[0]][0] + 1l) * dp[n][2]);
                    ans += ((dp[i[0]][0] + 1l) * dp[n][0]);
                }
                if (i[1] == 1) {
                    ans += ((dp[i[0]][3] + 1l) * dp[n][1]);
                    ans += ((dp[i[0]][1] + 1l) * dp[n][1]);
                }
                if (i[1] == 1) {
                    dp[n][1] += dp[i[0]][1] + 1;
                    dp[n][3] += (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] += dp[i[0]][0] + 1;
                    dp[n][2] += (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }
            }
        }

        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();
            int[] from = new int[n - 1];
            int[] to = new int[n - 1];
            int[] weight = new int[n - 1];
            for (int i = 0; i < n - 1; i++) {
                from[i] = in.scanInt();
                to[i] = in.scanInt();
                weight[i] = in.scanInt();
            }
            dp = new long[n + 1][4];
            G = CodeHash.packGraphW(from, to, weight, n);
            ans = 0;
            findIt(1, -1);
            out.println(ans);

        }

    }

    static class CodeHash {
        public static int[][][] packGraphW(int[] from, int[] to, int[] w, int n) {
            return packGraphW(from, to, w, n, from.length);
        }

        public static int[][][] packGraphW(int[] from, int[] to, int[] w, int n, int m) {
            int[][][] g = new int[n + 1][][];
            int[] p = new int[n + 1];
            for (int i = 0; i < m; i++) p[from[i]]++;
            for (int i = 0; i < m; i++) p[to[i]]++;
            for (int i = 0; i <= n; i++) g[i] = new int[p[i]][2];
            for (int i = 0; i < m; i++) {
                --p[from[i]];
                g[from[i]][p[from[i]]][0] = to[i];
                g[from[i]][p[from[i]]][1] = w[i];
                --p[to[i]];
                g[to[i]][p[to[i]]][0] = from[i];
                g[to[i]][p[to[i]]][1] = w[i];
            }
            return g;
        }

    }

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

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

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

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

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

    }
}


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

/**
 * @author khokharnikunj8
 */

public class Main {
    public static void main(String[] args) {
        new Thread(null, new Runnable() {
            public void run() {
                new Main().solve();
            }
        }, "1", 1 << 26).start();
    }

    void solve() {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        D01Tree solver = new D01Tree();
        solver.solve(1, in, out);
        out.close();
    }

    static class D01Tree {
        int[][][] G;
        long[][] dp;
        long ans;

        public void findIt(int n, int p) {
            for (int[] i : G[n]) {
                if (i[0] == p) continue;
                findIt(i[0], n);
                if (i[1] == 1) {
                    dp[n][1] += dp[i[0]][1] + 1;
                    dp[n][3] += (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] += dp[i[0]][0] + 1;
                    dp[n][2] += (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }
            }
            ans += (dp[n][0] * 2l);
            ans += (dp[n][1] * 2l);
            ans += dp[n][2] - dp[n][0];
            ans += dp[n][3] - dp[n][1];

            for (int[] i : G[n]) {
                if (i[0] == p) continue;
                if (i[1] == 1) {
                    dp[n][1] -= dp[i[0]][1] + 1;
                    dp[n][3] -= (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] -= dp[i[0]][0] + 1;
                    dp[n][2] -= (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }

                if (i[1] == 0) {
                    ans += ((dp[i[0]][0] + 1l) * (dp[n][0]));
                    ans += ((dp[i[0]][0] + 1l) * (dp[n][2] - dp[n][0]));
                    ans += ((dp[i[0]][0] + 1l) * (dp[n][1]));
                }
                if (i[1] == 1) {
                    ans += ((dp[i[0]][3] + 1l) * (dp[n][1]));
                }

                if (i[1] == 1) {
                    dp[n][1] += dp[i[0]][1] + 1;
                    dp[n][3] += (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] += dp[i[0]][0] + 1;
                    dp[n][2] += (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }
            }
        }

        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();
            int[] from = new int[n - 1];
            int[] to = new int[n - 1];
            int[] weight = new int[n - 1];
            for (int i = 0; i < n - 1; i++) {
                from[i] = in.scanInt();
                to[i] = in.scanInt();
                weight[i] = in.scanInt();
            }
            dp = new long[n + 1][4];
            G = CodeHash.packGraphW(from, to, weight, n);
            ans = 0;
            findIt(1, -1);
            out.println(ans);

        }

    }

    static class CodeHash {
        public static int[][][] packGraphW(int[] from, int[] to, int[] w, int n) {
            return packGraphW(from, to, w, n, from.length);
        }

        public static int[][][] packGraphW(int[] from, int[] to, int[] w, int n, int m) {
            int[][][] g = new int[n + 1][][];
            int[] p = new int[n + 1];
            for (int i = 0; i < m; i++) p[from[i]]++;
            for (int i = 0; i < m; i++) p[to[i]]++;
            for (int i = 0; i <= n; i++) g[i] = new int[p[i]][2];
            for (int i = 0; i < m; i++) {
                --p[from[i]];
                g[from[i]][p[from[i]]][0] = to[i];
                g[from[i]][p[from[i]]][1] = w[i];
                --p[to[i]];
                g[to[i]][p[to[i]]][0] = from[i];
                g[to[i]][p[to[i]]][1] = w[i];
            }
            return g;
        }

    }

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

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

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

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

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

    }
}


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

/**
 * @author khokharnikunj8
 */

public class Main {
    public static void main(String[] args) {
        new Thread(null, new Runnable() {
            public void run() {
                new Main().solve();
            }
        }, "1", 1 << 26).start();
    }

    void solve() {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        D01Tree solver = new D01Tree();
        solver.solve(1, in, out);
        out.close();
    }

    static class D01Tree {
        int[][][] G;
        long[][] dp;
        long ans;
    //
        public void findIt(int n, int p) {
            for (int[] i : G[n]) {
                if (i[0] == p) continue;
                findIt(i[0], n);
                if (i[1] == 1) {
                    dp[n][1] += dp[i[0]][1] + 1;
                    dp[n][3] += (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] += dp[i[0]][0] + 1;
                    dp[n][2] += (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }
            }
            ans += (dp[n][0] * 2l);
            ans += (dp[n][1] * 2l);
            ans += dp[n][2] - dp[n][0];
            ans += dp[n][3] - dp[n][1];

            for (int[] i : G[n]) {
                if (i[0] == p) continue;
                if (i[1] == 1) {
                    dp[n][1] -= dp[i[0]][1] + 1;
                    dp[n][3] -= (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] -= dp[i[0]][0] + 1;
                    dp[n][2] -= (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }

                if (i[1] == 0) {
                    ans += ((dp[i[0]][0] + 1l) * (dp[n][0]));
                    ans += ((dp[i[0]][0] + 1l) * (dp[n][2] - dp[n][0]));
                    ans += ((dp[i[0]][0] + 1l) * (dp[n][1]));
                }
                if (i[1] == 1) {
                    ans += ((dp[i[0]][3] + 1l + dp[i[0]][0]) * (dp[n][1]));
                }

                if (i[1] == 1) {
                    dp[n][1] += dp[i[0]][1] + 1;
                    dp[n][3] += (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] += dp[i[0]][0] + 1;
                    dp[n][2] += (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }
            }
        }

        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();
            int[] from = new int[n - 1];
            int[] to = new int[n - 1];
            int[] weight = new int[n - 1];
            for (int i = 0; i < n - 1; i++) {
                from[i] = in.scanInt();
                to[i] = in.scanInt();
                weight[i] = in.scanInt();
            }
            dp = new long[n + 1][4];
            G = CodeHash.packGraphW(from, to, weight, n);
            ans = 0;
            findIt(1, -1);
            out.println(ans);

        }

    }

    static class CodeHash {
        public static int[][][] packGraphW(int[] from, int[] to, int[] w, int n) {
            return packGraphW(from, to, w, n, from.length);
        }

        public static int[][][] packGraphW(int[] from, int[] to, int[] w, int n, int m) {
            int[][][] g = new int[n + 1][][];
            int[] p = new int[n + 1];
            for (int i = 0; i < m; i++) p[from[i]]++;
            for (int i = 0; i < m; i++) p[to[i]]++;
            for (int i = 0; i <= n; i++) g[i] = new int[p[i]][2];
            for (int i = 0; i < m; i++) {
                --p[from[i]];
                g[from[i]][p[from[i]]][0] = to[i];
                g[from[i]][p[from[i]]][1] = w[i];
                --p[to[i]];
                g[to[i]][p[to[i]]][0] = from[i];
                g[to[i]][p[to[i]]][1] = w[i];
            }
            return g;
        }

    }

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

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

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

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

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

    }
}


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

/**
 * @author khokharnikunj8
 */

public class Main {
    public static void main(String[] args) {
        new Thread(null, new Runnable() {
            public void run() {
                new Main().solve();
            }
        }, "1", 1 << 26).start();
    }

    void solve() {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        D01Tree solver = new D01Tree();
        solver.solve(1, in, out);
        out.close();
    }

    static class D01Tree {
        int[][][] G;
        long[][] dp;
        long ans;

        public void findIt(int n, int p) {
            for (int[] i : G[n]) {
                if (i[0] == p) continue;
                findIt(i[0], n);
                if (i[1] == 1) {
                    dp[n][1] += dp[i[0]][1] + 1;
                    dp[n][3] += (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] += dp[i[0]][0] + 1;
                    dp[n][2] += (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }
            }
            ans += (dp[n][0] * 2l);
            ans += (dp[n][1] * 2l);
            ans += dp[n][2] - dp[n][0];
            ans += dp[n][3] - dp[n][1];

            for (int[] i : G[n]) {
                if (i[0] == p) continue;
                if (i[1] == 1) {
                    dp[n][1] -= dp[i[0]][1] + 1;
                    dp[n][3] -= (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] -= dp[i[0]][0] + 1;
                    dp[n][2] -= (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }

                if (i[1] == 0) {
                    ans += ((dp[i[0]][0] + 1l) * (dp[n][0]));
                    ans += ((dp[i[0]][0] + 1l) * (dp[n][2] - dp[n][0]));
                    ans += ((dp[i[0]][0] + 1l) * (dp[n][1]));
                }
                if (i[1] == 1) {
                    ans += ((dp[i[0]][3] + 1l + dp[i[0]][0]) * (dp[n][1]));
                }

                if (i[1] == 1) {
                    dp[n][1] += dp[i[0]][1] + 1;
                    dp[n][3] += (dp[i[0]][3] + 1 + dp[i[0]][0]);
                } else {
                    dp[n][0] += dp[i[0]][0] + 1;
                    dp[n][2] += (dp[i[0]][2] + 1 + dp[i[0]][1]);
                }
            }
        }

        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();
            int[] from = new int[n - 1];
            int[] to = new int[n - 1];
            int[] weight = new int[n - 1];
            for (int i = 0; i < n - 1; i++) {
                from[i] = in.scanInt();
                to[i] = in.scanInt();
                weight[i] = in.scanInt();
            }
            dp = new long[n + 1][4];
            G = CodeHash.packGraphW(from, to, weight, n);
            ans = 0;
            findIt(1, -1);
            out.println(ans);

        }

    }

    static class CodeHash {
        public static int[][][] packGraphW(int[] from, int[] to, int[] w, int n) {
            return packGraphW(from, to, w, n, from.length);
        }

        public static int[][][] packGraphW(int[] from, int[] to, int[] w, int n, int m) {
            int[][][] g = new int[n + 1][][];
            int[] p = new int[n + 1];
            for (int i = 0; i < m; i++) p[from[i]]++;
            for (int i = 0; i < m; i++) p[to[i]]++;
            for (int i = 0; i <= n; i++) g[i] = new int[p[i]][2];
            for (int i = 0; i < m; i++) {
                --p[from[i]];
                g[from[i]][p[from[i]]][0] = to[i];
                g[from[i]][p[from[i]]][1] = w[i];
                --p[to[i]];
                g[to[i]][p[to[i]]][0] = from[i];
                g[to[i]][p[to[i]]][1] = w[i];
            }
            return g;
        }

    }

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

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

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

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

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

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.StringTokenizer;

public class E {
	static FastReader scan = new FastReader();
	static PrintWriter out = new PrintWriter(System.out);

	public static void main(String[] args) {
		Solver solver = new Solver();
		int testCases = 1;
		while (testCases-- > 0) solver.solve();
		out.close();
	}

	static class Solver {
		void solve() {
			int n = scan.nextInt();
			long res = 0;
			DSU[] set = new DSU[2];
			for(int i = 0; i < 2; i++) set[i] = new DSU(n);
			for(int i = 0; i < n-1; i++) {
				int a = scan.nextInt()-1, b = scan.nextInt()-1, c = scan.nextInt();
				set[c].union(a, b);
			}
			for(int i = 0; i < n; i++) {
				long aa = set[0].size[set[0].findParent(i)];
				long bb = set[1].size[set[1].findParent(i)];
				res += aa*bb-1;
			}
			out.println(res);
		}

	}

	//Sathvik's Template Stuff BELOW!!!!!!!!!!!!!!!!!!!!!!

	static class DSU {
		int[] root, size;
		int n;
		DSU(int n) {
			this.n = n;
			root = new int[n];
			size = new int[n];
			for(int i = 0; i < n; i++) {
				root[i] = i;
				size[i] = 1;
			}
		}
		int findParent(int idx) {
			while(root[idx] != idx) {
				root[idx] = root[root[idx]];
				idx = root[idx];
			}
			return idx;
		}
		boolean union(int x, int y) {
			int parX = findParent(x);
			int parY = findParent(y);
			if(parX == parY) return false;
			if(size[parX] < size[parY]) {
				root[parY] = parX;
				size[parX] += size[parY];
			} else {
				root[parX] = parY;
				size[parY] += size[parX];
			}
			return true;
		}
	}

	static class Extra {
		static void sort(int[] a) {
			Integer[] aa = new Integer[a.length];
			for (int i = 0; i < aa.length; i++) aa[i] = a[i];
			Arrays.sort(aa);
			for (int i = 0; i < aa.length; i++) a[i] = aa[i];
		}
		static void sort(long[] a) {
			Long[] aa = new Long[a.length];
			for (int i = 0; i < aa.length; i++) aa[i] = a[i];
			Arrays.sort(aa);
			for (int i = 0; i < aa.length; i++) a[i] = aa[i];
		}
		static void sort(double[] a) {
			Double[] aa = new Double[a.length];
			for (int i = 0; i < aa.length; i++) aa[i] = a[i];
			Arrays.sort(aa);
			for (int i = 0; i < aa.length; i++) a[i] = aa[i];
		}
		static void sort(char[] a) {
			Character[] aa = new Character[a.length];
			for (int i = 0; i < aa.length; i++) aa[i] = a[i];
			Arrays.sort(aa);
			for (int i = 0; i < aa.length; i++) a[i] = aa[i];
		}
		static long gcd(long a, long b) {
			while(b > 0) {
				long temp = b;
				b = a%b;
				a = temp;
			}
			return a;
		}
		static long lcm(long a, long b) {
			return a * (b / gcd(a,b));
		}
		static boolean isPrime(long n) {
			if (n <= 1) return false;
	        if (n <= 3) return true;
	        if (n % 2 == 0 || n % 3 == 0) return false;
	        for (long i = 5; i * i <= n; i = i + 6) {
	            if (n % i == 0 || n % (i + 2) == 0) return false;
	        }
	        return true;
		}
		static HashSet<Integer> sieve(int n) {
			boolean[] prime = new boolean[n+1];
			HashSet<Integer> res = new HashSet<>();
			for(int p = 2; p*p <= n; p++) {
				if(!prime[p]) {
					res.add(p);
					for(int i = p*p; i <= n; i+=p) prime[i] = true;
				}
			}
			return res;
		}
		static HashMap<Long, Integer> primeFactorization(long n) {
			HashMap<Long, Integer> res = new HashMap<>();
			while(n % 2 == 0) {
				res.put(2L, res.getOrDefault(2L, 0)+1);
				n/=2;
			}
			for(long i = 3; i*i <= n; i+=2) {
				while(n % i == 0) {
					res.put(i, res.getOrDefault(i, 0)+1);
					n/=i;
				}
			}
			if(n > 2) res.put(n, 1);
			return res;
		}
	}

	static class FastReader {
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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

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

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

		double[] nextDoubleArray(int n) {
			double[] a = new double[n];
			for (int i = 0; i < n; i++)
				a[i] = nextDouble();
			return a;
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}

}


//并查集解法

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class Main {
	static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	static final int N=(int) (1e6+10);
	static int sz1[]=new int[N];
	static int sz2[]=new int[N];
	static int fa1[]=new int[N];
	static int fa2[]=new int[N];
	static int find1(int x){
		return fa1[x]==x?x:(fa1[x]=find1(fa1[x]));
	}
	static int find2(int x){
		return fa2[x]==x?x:(fa2[x]=find2(fa2[x]));
	}
	static void merge1(int x,int y){
		int a=find1(x);
		int b=find1(y);
		if(a!=b){
			fa1[a]=b;
			sz1[b]+=sz1[a];
		}
	}
	static void merge2(int x,int y){
		int a=find2(x);
		int b=find2(y);
		if(a!=b){
			fa2[a]=b;
			sz2[b]+=sz2[a];
		}
	}
	public static void main(String[] args) {
		int n=nextInt();
		for(int i=1;i<=n;i++){
			sz1[i]=sz2[i]=1;
			fa1[i]=fa2[i]=i;
		}
		for(int i=1;i<n;i++){
			int u,v,w;
			u=nextInt();
			v=nextInt();
			w=nextInt();
			if(w==1){
				merge1(u,v);
			}else{
				merge2(u,v);
			}
		}
		long ans=0;
		for(int i=1;i<=n;i++){
			ans+=(long)sz1[find1(i)]*sz2[find2(i)]-1;
		}
		System.out.println(ans);
	}
	static int nextInt(){
		try {
			st.nextToken();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return (int)st.nval;
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
//我们不走先过1再过0的边，所以要么两点之间的路径全0，要么全1，要么先过0再过1，用并查集合并相邻的同样的路径
//并查集的解法有点没看懂，又找到一个树形dp的解法
public class Main {
	static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	static class edge{
		int v,next,w;
		public edge(int v, int next, int w) {
			super();
			this.v = v;
			this.next = next;
			this.w = w;
		}

	}
	static edge e[]=new edge[400010];
	static int p[]=new int[200010];
	static int fa[]=new int[200010];
	static int find(int x){
		return x==fa[x]?x:(fa[x]=find(fa[x]));
	}
	static void insert(int u,int v,int w){
		e[eid]=new edge(v,p[u],w);
		p[u]=eid++;
	}
	static int n,eid;
	static long ans=0;
	static int f[][]=new int[200010][4];
	static void dfs(int u,int fa){
		for(int i=p[u];i!=-1;i=e[i].next){
			int v=e[i].v;
			if(v==fa)
				continue;
			dfs(v,u);
			if(e[i].w==1){
				ans+=(long)2*f[u][1]*(f[v][1]+1);
				ans+=(long)(f[u][0]+f[u][3])*(f[v][1]+1);
				ans+=(long)f[u][1]*(f[v][0]+f[v][3]);

				f[u][1]+=f[v][1]+1;
				f[u][3]+=f[v][3];
				f[u][3]+=f[v][0];
			}else{
				ans+=(long)2*f[u][0]*(f[v][0]+1);
	            ans+=(long)(f[u][1]+f[u][2])*(f[v][0]+1);
	            ans+=(long)f[u][0]*(f[v][1]+f[v][2]);

	            f[u][0]+=f[v][0]+1;
	            f[u][2]+=f[v][2];
	            f[u][2]+=f[v][1];

			}
		}
		ans+=2*f[u][0];
		ans+=2*f[u][1];
		ans+=f[u][2];
		ans+=f[u][3];
	}
	public static void main(String[] args) {
		n=nextInt();
		eid=0;
		for(int i=0;i<=n;i++){
			//fa[i]=i;
			p[i]=-1;
		}
		int x,y,c;
		for(int i=1;i<n;i++){
			x=nextInt();
			y=nextInt();
			c=nextInt();
			insert(x,y,c);
			insert(y,x,c);
		}
		dfs(1,0);
		System.out.println(ans);
	}
	static int nextInt(){
		try {
			st.nextToken();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return (int)st.nval;
	}
}


//No sorceries shall prevail.
import java.util.*;
import java.io.*;
public class Main {

	static Scanner inp= new Scanner(System.in);
	static PrintWriter out= new PrintWriter(System.out);
	public static void main(String args[]) {
	   	Main g=new Main();
	   	g.main();
	   	out.close();
	}

	static int n;
	static ArrayList<Pair> list[];
	static long dp[][];
	static boolean vis[];
	static boolean vis2[];

	//Main
	void main() {

		n=inp.nextInt();
		list=new ArrayList[n];
		for(int i=0;i<n;i++) {
			list[i]=new ArrayList<Pair>();
		}
		for(int i=0;i<n-1;i++) {
			int x=inp.nextInt()-1;
			int y=inp.nextInt()-1;
			int color=inp.nextInt();
			list[x].add(new Pair(y,color));
			list[y].add(new Pair(x,color));
		}
		long gg=0;
		dp=new long[n][2];
		gg+=forest(0);
		gg+=forest(1);
		for(int i=0;i<n;i++) {
			//System.out.println(dp[i][0]+" "+dp[i][1]);
			gg+=(dp[i][0]*dp[i][1]);
		}
		System.out.println(gg);
	}

	static long forest(int color) {
		vis=new boolean[n];
		vis2=new boolean[n];
		long gg=0;
		for(int i=0;i<n;i++) {
			if(!vis[i]) {
				long elements=dfs(i,color);
				gg+=((elements)*(elements-1));
				assignDp(i,elements-1,color);
			}
		}
		return gg;
	}

	static void assignDp(int i, long value, int color) {
		vis2[i]=true;
		dp[i][color]=value;
		for(Pair x: list[i]) {
			if(vis2[x.to] || x.color!=color) continue;
			assignDp(x.to,value,color);
		}
	}

	static long dfs(int i,int color) {
		long c=1;
		vis[i]=true;
		for(Pair x: list[i]) {
			if(vis[x.to] || x.color!=color) continue;
			c+=dfs(x.to,color);
		}
		return c;
	}

	static class Pair {
		int to, color;
		Pair(){

		}
		Pair(int x, int y){
			to=x;
			color=y;
		}
	}

}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;

public class Main {
	private static final long MOD = 1000000007;
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	int p[][];

	void solve() {
		int n = ni();

		p = new int[n + 1][4];
		for (int i = 1; i <= n; i++) {
			p[i][0] = p[i][1] = i;
			p[i][2] = p[i][3] = 1;
		}

		for (int i = 1; i < n; i++) {
			int u = ni();
			int v = ni();
			int c = ni();
			merge(u, v, c);
		}

		long ans = 0;
		for (int i = 1; i <= n; i++) {
			if (i == getP(i, 0))
				ans += ((long) p[i][2]) * (p[i][2] - 1);
			if (i == getP(i, 1))
				ans += ((long) p[i][3]) * (p[i][3] - 1);
			ans += (((long) p[getP(i, 0)][2] - 1)) * (p[getP(i, 1)][3] - 1);
		}

		System.out.println(ans);
	}

	private void merge(int u, int v, int c) {
		int pu = getP(u, c);
		int pv = getP(v, c);
		if (pu != pv) {
			p[pu][c] = pv;
			p[pv][c + 2] += p[pu][c + 2];
		}
	}

	private int getP(int u, int c) {
		return p[u][c] == u ? u : (p[u][c] = getP(p[u][c], c));
	}

	StringBuffer sb = new StringBuffer();

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);
		Thread t = new Thread(null, null, "~", Runtime.getRuntime().maxMemory()) {
			@Override
			public void run() {
				long s = System.currentTimeMillis();
				solve();
				out.flush();
				if (!INPUT.isEmpty())
					tr(System.currentTimeMillis() - s + "ms");
			}
		};
		t.start();
		t.join();

		// long s = System.currentTimeMillis();
		// solve();
		// out.flush();
		// if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
	}

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

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

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

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

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

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

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

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

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

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

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

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

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;

public class Main {
	private static final long MOD = 1000000007;
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	int p[][];

	void solve() {
		int n = ni();

		p = new int[n + 1][4];
		for (int i = 1; i <= n; i++) {
			p[i][0] = p[i][1] = i;
			p[i][2] = p[i][3] = 1;
		}

		for (int i = 1; i < n; i++) {
			int u = ni();
			int v = ni();
			int c = ni();
			merge(u, v, c);
		}

		long ans = 0;
		for (int i = 1; i <= n; i++) {
			if (i == getP(i, 0))
				ans += p[i][2] * (p[i][2] - 1);
			if (i == getP(i, 1))
				ans += p[i][3] * (p[i][3] - 1);
			ans += (p[getP(i, 0)][2] - 1) * (p[getP(i, 1)][3] - 1);
		}

		System.out.println(ans);
	}

	private void merge(int u, int v, int c) {
		int pu = getP(u, c);
		int pv = getP(v, c);
		if (pu != pv) {
			p[pu][c] = pv;
			p[pv][c + 2] += p[pu][c + 2];
		}
	}

	private int getP(int u, int c) {
		while (u != p[u][c])
			u = p[u][c];
		return u;
	}

	StringBuffer sb = new StringBuffer();

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);
		Thread t = new Thread(null, null, "~", Runtime.getRuntime().maxMemory()) {
			@Override
			public void run() {
				long s = System.currentTimeMillis();
				solve();
				out.flush();
				if (!INPUT.isEmpty())
					tr(System.currentTimeMillis() - s + "ms");
			}
		};
		t.start();
		t.join();

		// long s = System.currentTimeMillis();
		// solve();
		// out.flush();
		// if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
	}

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

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

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

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

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

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

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

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

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

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

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

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

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;

public class Main {
	private static final long MOD = 1000000007;
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	int p[][];

	void solve() {
		int n = ni();

		p = new int[n + 1][4];
		for (int i = 1; i <= n; i++) {
			p[i][0] = p[i][1] = i;
			p[i][2] = p[i][3] = 1;
		}

		for (int i = 1; i < n; i++) {
			int u = ni();
			int v = ni();
			int c = ni();
			merge(u, v, c);
		}

		long ans = 0;
		for (int i = 1; i <= n; i++) {
			if (i == getP(i, 0))
				ans += ((long) p[i][2]) * (p[i][2] - 1);
			if (i == getP(i, 1))
				ans += ((long) p[i][3]) * (p[i][3] - 1);
			ans += (((long) p[getP(i, 0)][2] - 1)) * (p[getP(i, 1)][3] - 1);
		}

		System.out.println(ans);
	}

	private void merge(int u, int v, int c) {
		int pu = getP(u, c);
		int pv = getP(v, c);
		if (pu != pv) {
			p[pu][c] = pv;
			p[pv][c + 2] += p[pu][c + 2];
		}
	}

	private int getP(int u, int c) {
		while (u != p[u][c])
			u = p[u][c];
		return u;
	}

	StringBuffer sb = new StringBuffer();

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);
		Thread t = new Thread(null, null, "~", Runtime.getRuntime().maxMemory()) {
			@Override
			public void run() {
				long s = System.currentTimeMillis();
				solve();
				out.flush();
				if (!INPUT.isEmpty())
					tr(System.currentTimeMillis() - s + "ms");
			}
		};
		t.start();
		t.join();

		// long s = System.currentTimeMillis();
		// solve();
		// out.flush();
		// if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
	}

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

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

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

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

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

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

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

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

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

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

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

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

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class CF_1156D {

    static ArrayList<ArrayList<int[]>> adj = new ArrayList<>();

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedInputStream(System.in));
        PrintStream out = new PrintStream(new BufferedOutputStream(System.out));

        int n = in.nextInt();
        for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
        for (int i = 0; i < n - 1; i++) {
            int u = in.nextInt() - 1;
            int v = in.nextInt() - 1;
            int t = in.nextInt();

            adj.get(u).add(new int[]{v, t});
            adj.get(v).add(new int[]{u, t});
        }

        boolean[] v0 = new boolean[n];
        boolean[] v1 = new boolean[n];
        long[] s0 = new long[n];
        long[] s1 = new long[n];

        long ret = 0;
        for (int i = 0; i < n; i++) {
            int size = sizeDFS(i, -1, 0, v0);

            if (size != -1 && size != 1) ret += 1L * size * size;
            fill(i, -1, 0, size, s0);

            size = sizeDFS(i, -1, 1, v1);
            if (size != -1 && size != 1) ret += 1L * size * size;

            fill(i, -1, 1, size, s1);
        }

        for (int i = 0; i < n; i++) {
            ret += Math.max((s0[i] - 1) * (s1[i] - 1) - 1, 0);
        }

        ret -= n;

        out.println(ret);

        out.close();
        in.close();
    }

    static int sizeDFS(int curr, int p, int t, boolean[] v) {
        if (v[curr]) return -1;
        v[curr] = true;

        int ret = 1;
        for (int[] u : adj.get(curr)) {
            if (u[0] != p && u[1] == t) {
                ret += sizeDFS(u[0], curr, t, v);
            }
        }
        return ret;
    }

    static void fill(int curr, int p, int t, int size, long[] sizes) {
        if (size == -1) return;

        sizes[curr] = size;
        for (int[] u : adj.get(curr)) {
            if (u[0] != p && u[1] == t) {
                fill(u[0], curr, t, size, sizes);
            }
        }
    }
}


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class CF_1156D {

    static ArrayList<ArrayList<int[]>> adj = new ArrayList<>();
    static int MOD = (int) 1e9 + 7;

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedInputStream(System.in));
        PrintStream out = new PrintStream(new BufferedOutputStream(System.out));

        int n = in.nextInt();
        for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
        for (int i = 0; i < n - 1; i++) {
            int u = in.nextInt() - 1;
            int v = in.nextInt() - 1;
            int t = in.nextInt();

            adj.get(u).add(new int[]{v, t});
            adj.get(v).add(new int[]{u, t});
        }

        boolean[] v0 = new boolean[n];
        boolean[] v1 = new boolean[n];
        long[] s0 = new long[n];
        long[] s1 = new long[n];

        long ret = 0;
        for (int i = 0; i < n; i++) {

            int size = sizeDFS(i, -1, 0, v0);

            if (size != -1) ret += (size - 1) * (size - 1);
            ret %= MOD;
            fill(i, -1, 0, size, s0);

            size = sizeDFS(i, -1, 1, v1);
            if (size != -1) ret += (size - 1) * (size - 1);
            ret %= MOD;

            fill(i, -1, 1, size, s1);
        }

        for (int i = 0; i < n; i++) {
            ret += Math.max(2 * ((s0[i] - 1) * (s1[i] - 1) - 1), 0);
            ret %= MOD;
        }

        out.println(ret);

        out.close();
        in.close();
    }

    static int sizeDFS(int curr, int p, int t, boolean[] v) {
        if (v[curr]) return -1;
        v[curr] = true;

        int ret = 1;
        for (int[] u : adj.get(curr)) {
            if (u[0] != p && u[1] == t) {
                ret += sizeDFS(u[0], curr, t, v);
            }
        }
        return ret;
    }

    static void fill(int curr, int p, int t, int size, long[] sizes) {
        if (size == -1) return;

        sizes[curr] = size;
        for (int[] u : adj.get(curr)) {
            if (u[0] != p && u[1] == t) {
                fill(u[0], curr, t, size, sizes);
            }
        }
    }
}


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class CF_1156D {

    static ArrayList<ArrayList<int[]>> adj = new ArrayList<>();
    static int MOD = (int) 1e9 + 7;

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedInputStream(System.in));
        PrintStream out = new PrintStream(new BufferedOutputStream(System.out));

        int n = in.nextInt();
        for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
        for (int i = 0; i < n - 1; i++) {
            int u = in.nextInt() - 1;
            int v = in.nextInt() - 1;
            int t = in.nextInt();

            adj.get(u).add(new int[]{v, t});
            adj.get(v).add(new int[]{u, t});
        }

        boolean[] v0 = new boolean[n];
        boolean[] v1 = new boolean[n];
        long[] s0 = new long[n];
        long[] s1 = new long[n];

        long ret = 0;
        for (int i = 0; i < n; i++) {

            int size = sizeDFS(i, -1, 0, v0);

            if (size != -1 && size != 1) ret += 1L * size * size;
            ret %= MOD;
            fill(i, -1, 0, size, s0);

            size = sizeDFS(i, -1, 1, v1);
            if (size != -1 && size != 1) ret += 1L * size * size;
            ret %= MOD;

            fill(i, -1, 1, size, s1);
        }

        for (int i = 0; i < n; i++) {
            ret += Math.max((s0[i] - 1) * (s1[i] - 1) - 1, 0);
            ret %= MOD;
        }

        ret -= n;

        out.println(ret);

        out.close();
        in.close();
    }

    static int sizeDFS(int curr, int p, int t, boolean[] v) {
        if (v[curr]) return -1;
        v[curr] = true;

        int ret = 1;
        for (int[] u : adj.get(curr)) {
            if (u[0] != p && u[1] == t) {
                ret += sizeDFS(u[0], curr, t, v);
            }
        }
        return ret;
    }

    static void fill(int curr, int p, int t, int size, long[] sizes) {
        if (size == -1) return;

        sizes[curr] = size;
        for (int[] u : adj.get(curr)) {
            if (u[0] != p && u[1] == t) {
                fill(u[0], curr, t, size, sizes);
            }
        }
    }
}


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class CF_1156D {

    static ArrayList<ArrayList<int[]>> adj = new ArrayList<>();
    static int MOD = (int) 1e9 + 7;

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedInputStream(System.in));
        PrintStream out = new PrintStream(new BufferedOutputStream(System.out));

        int n = in.nextInt();
        for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
        for (int i = 0; i < n - 1; i++) {
            int u = in.nextInt() - 1;
            int v = in.nextInt() - 1;
            int t = in.nextInt();

            adj.get(u).add(new int[]{v, t});
            adj.get(v).add(new int[]{u, t});
        }

        boolean[] v0 = new boolean[n];
        boolean[] v1 = new boolean[n];
        long[] s0 = new long[n];
        long[] s1 = new long[n];

        long ret = 0;
        for (int i = 0; i < n; i++) {

            int size = sizeDFS(i, -1, 0, v0);

            if (size != -1) ret += (size - 1) * (size - 1);
            ret %= MOD;
            fill(i, -1, 0, size, s0);

            size = sizeDFS(i, -1, 1, v1);
            if (size != -1) ret += (size - 1) * (size - 1);
            ret %= MOD;

            fill(i, -1, 1, size, s1);
        }

        System.out.println(Arrays.toString(s0));
        System.out.println(Arrays.toString(s1));

        for (int i = 0; i < n; i++) {
            ret += 2 * (s0[i] - 1) * (s1[i] - 1) - 2;
            ret %= MOD;
        }

        out.println(ret);

        out.close();
        in.close();
    }

    static int sizeDFS(int curr, int p, int t, boolean[] v) {
        if (v[curr]) return -1;
        v[curr] = true;

        int ret = 1;
        for (int[] u : adj.get(curr)) {
            if (u[0] != p && u[1] == t) {
                ret += sizeDFS(u[0], curr, t, v);
            }
        }
        return ret;
    }

    static void fill(int curr, int p, int t, int size, long[] sizes) {
        if (size == -1) return;

        sizes[curr] = size;
        for (int[] u : adj.get(curr)) {
            if (u[0] != p && u[1] == t) {
                fill(u[0], curr, t, size, sizes);
            }
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class default_tds {
    static int[] dsu0;
    static int[] dsu1;
    static int[] wt0;
    static int[] wt1;
    public static void main(String[] args) {
        in = new FastReader();
        int n=ni();
        dsu0=new int[n];
        dsu1=new int[n];
        wt1=new int[n];
        wt0=new int[n];
        for (int i=0;i<n;i++){
            dsu1[i]=i;
            dsu0[i]=i;
           wt0[i]= wt1[i]=1;
        }
        for (int i=1;i<n;i++){
            int a=ni()-1;
            int b=ni()-1;
            int c=ni();
            merge(a,b,c);
        }
        long ans=0;
        for (int i=0;i<n;i++){
            int p0=getP(i,0);
            int p1=getP(i,1);
            if (p0==i){
                ans+=(long)wt0[i]*(long)(wt0[i]-(long)1);
            }
            if (p1==i){
                ans+=(long)wt1[i]*(long)((long)wt1[i]-(long)1);
            }
            if (wt0[p0]>0&&wt1[p1]>0)
            ans+=(long)((long)wt0[p0]-(long)1)*((long)wt1[p1]-(long)1);
        }
        System.out.println(ans);

    }
    static void merge(int node1,int node2,int c){
        if (c==0){
            int p1=getP(node1,c);
            int p2=getP(node2,c);
            if (wt0[p1]>=wt0[p2]){
                dsu0[p2]=p1;
                wt0[p1]+=wt0[p2];
                wt0[p2]=0;
            }else {
                dsu0[p1]=p2;
                wt0[p2]+=wt0[p1];
                wt0[p1]=0;
            }
        }else {
            //c==1
            int p1=getP(node1,c);
            int p2=getP(node2,c);
            if (wt1[p1]>=wt1[p2]){
                dsu1[p2]=p1;
                wt1[p1]+=wt1[p2];
                wt1[p2]=0;
            }else {
                dsu1[p1]=p2;
                wt1[p2]+=wt1[p1];
                wt1[p1]=0;
            }
        }
    }

    static int getP(int node,int c){
        if (c==0){
            if (dsu0[node]==node)return node;
            int p=getP(dsu0[node],c);
          return   dsu0[node]=p;
        }else {
            //c==1
            if (dsu1[node]==node)return node;
            int p=getP(dsu1[node],c);
            return   dsu1[node]=p;
        }
    }
    static class pair{
        int x;
        int y;
        pair(int x,int y){
            this.x=x;
            this.y=y;
        }
    }
    public static long binarySearch(long low, long high) {
        while (high - low > 1) {
            long mid = (high - low)/2 + low;
            //System.out.println(mid);
            if (works(mid)) {
                high = mid;
            } else {
                low = mid;
            }
        }
        return (works(low) ? low : high);
    }
    static long fast_exp_with_mod(long base, long exp) {
        long MOD=1000000000+7;
        long res=1;
        while(exp>0) {
            if(exp%2==1) res=(res*base)%MOD;
            base=(base*base)%MOD;
            exp/=2;
        }
        return res%MOD;
    }
    public static long gcd(long a, long b)
    {
        if (a == 0)
            return b;
        return gcd(b%a, a);
    }
    static class my_no{
        long num;
        long denom;

        @Override
        public String toString() {
            if (denom<0){
                this.num=-this.num;
                this.denom=-this.denom;
            }
            if (num==0)return "0";
            return (num+"/"+denom);
        }

        my_no(int no){
            this.num=no;
            this.denom=1;
        }
        my_no(long num,long denom){
            this.num=num;
            this.denom=denom;
        }

        my_no multiply(my_no obj){
            long num1=obj.num;
            long denom1=obj.denom;
            long n=num1*num;
            long d=denom1*denom;
            long gcd=gcd(n,d);
            n/=gcd;
            d/=gcd;
            return new my_no(n,d);

        }
//        my_no multiply(my_no obj){
//            long num1=obj.num;
//            long denom1=obj.denom;
//            long num2=this.num;
//            long denom2=this.denom;
//
//        }

        my_no multiply(int no){
            long n=num*no;
            long d=denom;
            long gcd=gcd(n,d);
            n/=gcd;
            d/=gcd;
            return new my_no(n,d);

        }
    }
    static void memset(int[][] arr,int val){
        for (int i=0;i<arr.length;i++){
            for (int j=0;j<arr[i].length;j++){
                arr[i][j]=val;
            }
        }
    }
    static void memset(int[] arr,int val){
        for (int i=0;i<arr.length;i++){
            arr[i]=val;
        }
    }

    static void memset(long[][] arr,long val){
        for (int i=0;i<arr.length;i++){
            for (int j=0;j<arr[i].length;j++){
                arr[i][j]=val;
            }
        }
    }
    static void memset(long[] arr,long val){
        for (int i=0;i<arr.length;i++){
            arr[i]=val;
        }
    }
    static private boolean works(long test){
        return true;
    }

    static void reverse(char[] arr ,int i,int j){
        if (i==j)
            return;
        while (i<j){
            char temp=arr[i];
            arr[i]=arr[j];
            arr[j]=temp;
            ++i;
            --j;
        }
    }
    static int[]  takeIntegerArrayInput(int no){
        int[] arr=new int[no];
        for (int i=0;i<no;++i){
            arr[i]=ni();
        }
        return arr;
    }
    static long fast_Multiply(long no , long pow){
        long result=1;
        while (pow>0){
            if ((pow&1)==1){
                result=result*no;
            }
            no=no*no;
            pow>>=1;
        }
        return result;
    }

    static long[]  takeLongArrayInput(int no){
        long[] arr=new long[no];
        for (int i=0;i<no;++i){
            arr[i]=ni();
        }
        return arr;
    }
    static final long MOD = (long)1e9+7;
    static FastReader in;

    static void p(Object o){
        System.out.print(o);
    }

    static void pn(Object o){
        System.out.println(o);
    }

    static String n(){
        return in.next();
    }

    static String nln(){
        return in.nextLine();
    }

    static int ni(){
        return Integer.parseInt(in.next());
    }

    static int[] ia(int N){
        int[] a = new int[N];
        for(int i = 0; i<N; i++)a[i] = ni();
        return a;
    }

    static long[] la(int N){
        long[] a = new long[N];
        for(int i = 0; i<N; i++)a[i] = nl();
        return a;
    }

    static long nl(){
        return Long.parseLong(in.next());
    }

    static double nd(){
        return Double.parseDouble(in.next());
    }

    static class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

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

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
    static void println(String[] arr){
        for (int i=0;i<arr.length;++i){
            System.out.println(arr[i]);
        }
    }

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class default_tds {
    static int[] dsu0;
    static int[] dsu1;
    static int[] wt0;
    static int[] wt1;
    public static void main(String[] args) {
        in = new FastReader();
        int n=ni();
        dsu0=new int[n];
        dsu1=new int[n];
        wt1=new int[n];
        wt0=new int[n];
        for (int i=0;i<n;i++){
            dsu1[i]=i;
            dsu0[i]=i;
           wt0[i]= wt1[i]=1;
        }
        for (int i=1;i<n;i++){
            int a=ni()-1;
            int b=ni()-1;
            int c=ni();
            merge(a,b,c);
        }
        long ans=0;
        for (int i=0;i<n;i++){
            int p0=getP(i,0);
            int p1=getP(i,1);
            if (p0==i){
                ans+=wt0[i]*(wt0[i]-1);
            }
            if (p1==i){
                ans+=wt1[i]*(wt1[i]-1);
            }
            if (wt0[p0]>0&&wt1[p1]>0)
            ans+=(wt0[p0]-1)*(wt1[p1]-1);
        }
        System.out.println(ans);

    }
    static void merge(int node1,int node2,int c){
        if (c==0){
            int p1=getP(node1,c);
            int p2=getP(node2,c);
            if (wt0[p1]>=wt0[p2]){
                dsu0[p2]=p1;
                wt0[p1]+=wt0[p2];
                wt0[p2]=0;
            }else {
                dsu0[p1]=p2;
                wt0[p2]+=wt0[p1];
                wt0[p1]=0;
            }
        }else {
            //c==1
            int p1=getP(node1,c);
            int p2=getP(node2,c);
            if (wt1[p1]>=wt1[p2]){
                dsu1[p2]=p1;
                wt1[p1]+=wt1[p2];
                wt1[p2]=0;
            }else {
                dsu1[p1]=p2;
                wt1[p2]+=wt1[p1];
                wt1[p1]=0;
            }
        }
    }

    static int getP(int node,int c){
        if (c==0){
            if (dsu0[node]==node)return node;
            int p=getP(dsu0[node],c);
          return   dsu0[node]=p;
        }else {
            //c==1
            if (dsu1[node]==node)return node;
            int p=getP(dsu1[node],c);
            return   dsu1[node]=p;
        }
    }
    static class pair{
        int x;
        int y;
        pair(int x,int y){
            this.x=x;
            this.y=y;
        }
    }
    public static long binarySearch(long low, long high) {
        while (high - low > 1) {
            long mid = (high - low)/2 + low;
            //System.out.println(mid);
            if (works(mid)) {
                high = mid;
            } else {
                low = mid;
            }
        }
        return (works(low) ? low : high);
    }
    static long fast_exp_with_mod(long base, long exp) {
        long MOD=1000000000+7;
        long res=1;
        while(exp>0) {
            if(exp%2==1) res=(res*base)%MOD;
            base=(base*base)%MOD;
            exp/=2;
        }
        return res%MOD;
    }
    public static long gcd(long a, long b)
    {
        if (a == 0)
            return b;
        return gcd(b%a, a);
    }
    static class my_no{
        long num;
        long denom;

        @Override
        public String toString() {
            if (denom<0){
                this.num=-this.num;
                this.denom=-this.denom;
            }
            if (num==0)return "0";
            return (num+"/"+denom);
        }

        my_no(int no){
            this.num=no;
            this.denom=1;
        }
        my_no(long num,long denom){
            this.num=num;
            this.denom=denom;
        }

        my_no multiply(my_no obj){
            long num1=obj.num;
            long denom1=obj.denom;
            long n=num1*num;
            long d=denom1*denom;
            long gcd=gcd(n,d);
            n/=gcd;
            d/=gcd;
            return new my_no(n,d);

        }
//        my_no multiply(my_no obj){
//            long num1=obj.num;
//            long denom1=obj.denom;
//            long num2=this.num;
//            long denom2=this.denom;
//
//        }

        my_no multiply(int no){
            long n=num*no;
            long d=denom;
            long gcd=gcd(n,d);
            n/=gcd;
            d/=gcd;
            return new my_no(n,d);

        }
    }
    static void memset(int[][] arr,int val){
        for (int i=0;i<arr.length;i++){
            for (int j=0;j<arr[i].length;j++){
                arr[i][j]=val;
            }
        }
    }
    static void memset(int[] arr,int val){
        for (int i=0;i<arr.length;i++){
            arr[i]=val;
        }
    }

    static void memset(long[][] arr,long val){
        for (int i=0;i<arr.length;i++){
            for (int j=0;j<arr[i].length;j++){
                arr[i][j]=val;
            }
        }
    }
    static void memset(long[] arr,long val){
        for (int i=0;i<arr.length;i++){
            arr[i]=val;
        }
    }
    static private boolean works(long test){
        return true;
    }

    static void reverse(char[] arr ,int i,int j){
        if (i==j)
            return;
        while (i<j){
            char temp=arr[i];
            arr[i]=arr[j];
            arr[j]=temp;
            ++i;
            --j;
        }
    }
    static int[]  takeIntegerArrayInput(int no){
        int[] arr=new int[no];
        for (int i=0;i<no;++i){
            arr[i]=ni();
        }
        return arr;
    }
    static long fast_Multiply(long no , long pow){
        long result=1;
        while (pow>0){
            if ((pow&1)==1){
                result=result*no;
            }
            no=no*no;
            pow>>=1;
        }
        return result;
    }

    static long[]  takeLongArrayInput(int no){
        long[] arr=new long[no];
        for (int i=0;i<no;++i){
            arr[i]=ni();
        }
        return arr;
    }
    static final long MOD = (long)1e9+7;
    static FastReader in;

    static void p(Object o){
        System.out.print(o);
    }

    static void pn(Object o){
        System.out.println(o);
    }

    static String n(){
        return in.next();
    }

    static String nln(){
        return in.nextLine();
    }

    static int ni(){
        return Integer.parseInt(in.next());
    }

    static int[] ia(int N){
        int[] a = new int[N];
        for(int i = 0; i<N; i++)a[i] = ni();
        return a;
    }

    static long[] la(int N){
        long[] a = new long[N];
        for(int i = 0; i<N; i++)a[i] = nl();
        return a;
    }

    static long nl(){
        return Long.parseLong(in.next());
    }

    static double nd(){
        return Double.parseDouble(in.next());
    }

    static class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

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

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
    static void println(String[] arr){
        for (int i=0;i<arr.length;++i){
            System.out.println(arr[i]);
        }
    }

}


#include<bits/stdc++.h>

using namespace std;

const int N = 200043;

int p[2][N];
int siz[2][N];

int get(int x, int c)
{
	if(p[c][x] == x)
		return x;
	return p[c][x] = get(p[c][x], c);
}

void merge(int x, int y, int c)
{
	x = get(x, c);
	y = get(y, c);
	if(siz[c][x] < siz[c][y])
		swap(x, y);
	p[c][y] = x;
	siz[c][x] += siz[c][y];
}

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 0; i < n; i++)
	{
		p[0][i] = p[1][i] = i;
		siz[0][i] = siz[1][i] = 1;
	}
	for(int i = 0; i < n - 1; i++)
	{
		int x, y, c;
		scanf("%d %d %d", &x, &y, &c);
		--x;
		--y;
		merge(x, y, c);
	}
	long long ans = 0;
	for(int i = 0; i < n; i++)
	{
		if(p[0][i] == i)
			ans += siz[0][i] * 1ll * (siz[0][i] - 1);
		if(p[1][i] == i)
			ans += siz[1][i] * 1ll * (siz[1][i] - 1);
		ans += (siz[0][get(i, 0)] - 1) * 1ll * (siz[1][get(i, 1)] - 1);
	}
	cout << ans << endl;
}


#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
vector<vector<int> > g, w;
bool usd[ 100005 ];
int x ;
int f( int u ){
    usd[ u ] = true;
    int res = 0;
    for( int i = 0; i < g[u].size(); i++){
        if ( usd[ g[u][i] ]) continue;
        res += w[u][i] + f( g[u][i] );
    }
    return res;
}

int main(){
    int n;
    cin >> n;
    g = w = vector<vector<int> > (n);
    memset( usd, 0, sizeof usd);
    int sum = 0;
    for( int i = 0; i < n - 1; i++){
        int u,v,p;
        cin >> u >> v >> p;
        u--,v--;
        g[u].push_back( v );
        g[v].push_back( u );
        w[u].push_back( p );
        w[v].push_back( p );
        sum += p;
    }
    cout << 2 * sum - x << endl;
}


#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman001 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define F first
#define S second
#define inFile(t) freopen((t),"r",stdin)
#define outFile(t) freopen((t),"w",stdout)
#define pb push_back
#define pf push_front
#define Pb pop_back
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define Pf pop_front
#define sz size
#define MP make_pair
#define Pc __builtin_popcount
#define pi 2*acos(0)
#define BiEdge(v,a,b) (v)[(a)].pb(b),(v)[(b)].pb(a)
#define mod 1000000007
#define point complex<ld>
#define X real()
#define Y imag()
#define pll pair<ll,ll>
#define pii pair<int,int>
#define cross(a,b)(conj(a)*(b)).imag()
#define dot(a,b) (conj(a)*(b)).real()
#define rectangle pair<coordinate,coordinate>
#define line tuple<ll,ll,ll>
#define EPS 1e-7
#define polygon vector<point>
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
int const N = 2*1e5+5,M = 105;
using namespace std;
ll rep[N][2],si[N][2],n,ans;
ll find(ll u,ll c)
{
    return (rep[u][c] == u)?u:rep[u][c] = find(rep[u][c],c);
}
void join(ll u,ll v,ll c)
{
    u = rep[u][c],v = rep[v][c];
    if(u == v)
        return;
    if(si[u] < si[v])
        swap(u,v);
    rep[v][c] = u;
    si[u][c]+=si[v][c];
}
int main()
{
    abdelrahman001
    cin >> n;
    for(int i = 1;i<=n;i++)
        rep[i][0] = rep[i][1] = i,si[i][0] = si[i][1] = 1;
    for(int i = 1,a,b,c;i<n;i++)
        cin >> a >> b >> c,join(a,b,c);
    for(int i = 1;i<=n;i++)
    {
        if(rep[find(i,0)][0] == i)
            ans+= si[i][0]*(si[i][0] -1);
        if(rep[find(i,1)][1] == i)
            ans+=si[i][1]*(si[i][1] -1);
        ans+=(si[find(i,0)][0]-1) * (si[find(i,1)][1]-1);
    }
    cout << ans;
    return 0;
}


#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman001 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define F first
#define S second
#define inFile(t) freopen((t),"r",stdin)
#define outFile(t) freopen((t),"w",stdout)
#define pb push_back
#define pf push_front
#define Pb pop_back
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define Pf pop_front
#define sz size
#define MP make_pair
#define Pc __builtin_popcount
#define pi 2*acos(0)
#define BiEdge(v,a,b) (v)[(a)].pb(b),(v)[(b)].pb(a)
#define mod 1000000007
#define point complex<ld>
#define X real()
#define Y imag()
#define pll pair<ll,ll>
#define pii pair<int,int>
#define cross(a,b)(conj(a)*(b)).imag()
#define dot(a,b) (conj(a)*(b)).real()
#define rectangle pair<coordinate,coordinate>
#define line tuple<ll,ll,ll>
#define EPS 1e-7
#define polygon vector<point>
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
int const N = 2*1e5+5,M = 105;
using namespace std;
ll rep[N][2],si[N][2],n,ans;
ll find(ll u,ll c)
{
    return (rep[u][c] == u)?u:rep[u][c] = find(rep[u][c],c);
}
void join(ll u,ll v,ll c)
{
    u = rep[u][c],v = rep[v][c];
    if(u == v)
        return;
    if(si[u] < si[v])
        swap(u,v);
    rep[v][c] = u;
    si[u][c]+=si[v][c];
}
int main()
{
    abdelrahman001
    cin >> n;
    for(int i = 1;i<=n;i++)
        rep[i][0] = rep[i][1] = i,si[i][0] = si[i][1] = 1;
    for(int i = 1,a,b,c;i<n;i++)
        cin >> a >> b >> c,join(a,b,c);
    for(int i = 1;i<=n;i++)
    {
        if(rep[find(i,0)][0] == i)
            ans+= si[find(i,0)][0]*(si[find(i,0)][0] -1);
        if(rep[find(i,1)][1] == i)
            ans+=si[find(i,1)][1]*(si[find(i,1)][1] -1);
        ans+=(si[find(i,0)][0]-1) * (si[find(i,1)][1]-1);
    }
    cout << ans;
    return 0;
}


n, v = gets.chomp.split(/ /).map(&:to_i)
sellers = []
n.times do
    line = gets.chomp.split(/ /).map(&:to_i)
    prices = line[1...line.length]
    sellers << prices
end
deal = []
sellers.each_index do |seller|
    prices = sellers[seller]
    prices.each do |price|
        if price < v
            deal << seller + 1
        end
    end
end
deal.sort!
puts deal.length
puts deal.join(" ")


n, v = gets.chomp.split(/ /).map(&:to_i)
sellers = []
n.times do
    line = gets.chomp.split(/ /).map(&:to_i)
    prices = line[1...line.length]
    sellers << prices
end
deal = []
sellers.each_index do |seller|
    prices = sellers[seller]
    prices.each do |price|
        if price < v
            deal << seller + 1
            break
        end
    end
end
deal.sort!
puts deal.length
puts deal.join(" ")


n,v=gets.split.map{|e| e.to_i}
ans=[]
n.times{|i|
	x=gets.split.map{|e| e.to_i}
	x.shift
	if x.min<v then
		ans<<(i+1)
	end
}
puts ans.size
if ans.size>0 then
	puts ans*" "
end


# coding: utf-8

n, v = gets.split.map(&:to_i)
dealers = []
n.times {
    dealer, *prices = gets.split.map(&:to_i)
    prices.each { |i|
        if i < v
            dealers << dealer
            break
        end
    }
}
puts dealers.length
puts dealers.join(' ')


# coding: utf-8

n, v = gets.split.map(&:to_i)
dealers = []
n.times { |dealer|
    _, *prices = gets.split.map(&:to_i)
    if v > prices.min
        dealers << dealer + 1
    end
}
puts dealers.length
puts dealers.join(' ')


nk = gets.chomp.split.map(&:to_i)
n = nk[0]
k = nk[1]
arr = []
count = 0
a = []
for i in (0..n-1)
	arr << gets.chomp.split.map(&:to_i)
	arr[i].delete_at(0)
	if arr[i].min < k
		count += 1
		a << i+1
	end
end

puts count
for num in a
	print num
	print " "
end


n,v=gets.split.map(&:to_i)
a=1.step(n).select{|i|
gets.split.map(&:to_i)[1..-1].any?{|e|e<v}
}
p a.size
puts a*' '


first_line=gets().split(" ")
ans=[]
n=first_line[0].to_i;money=first_line[1].to_i
for i in 0...n
  line=gets().split(" ")
  line.map!{|x| x.to_i}
  for j in 1...line.size
    if line[j]<money
      ans<< i+1
      break
    end
  end
  ans.sort!

end
if ans.size==0
  puts 0
else
  puts ans.size
  puts ans.join(" ")
end


first_line=gets().split(" ")
ans=[]
n=first_line[0].to_i;money=first_line[1].to_i
for i in 0...n
  line=gets().split(" ")
  line.map!{|x| x.to_i}
  for i in 1...line.size
    if line[i]<money
      ans<<line[0]
      break
    end
  end
  ans.sort!

end
if ans.size==0
  puts 0
else
  puts ans.size
  puts ans.join(" ")
end


first_line=gets().split(" ")
ans=[]
n=first_line[0].to_i;money=first_line[1].to_i
for i in 0...n
  line=gets().split(" ")
  line.map!{|x| x.to_i}
  for i in 1...line.size
    if line[i]<money
      ans<<line[0]
      break
    end
  end
  ans.sort!

end
if ans.size==0
  puts 0
else
  puts ans.join(" ")
end


n,v = gets.split(" ").map(&:to_i)
sellers = []
(1..n).each do |s|
  sellers << s if gets.split(" ").map(&:to_i)[1..-1].any?{|x| v > x}
end
puts sellers.count
puts sellers.join(" ")


n,v = gets.split.map(&:to_i)
d = (1..n).select { |_|
  items = gets.split.map(&:to_i).drop 1
  items.select { |i| v > i }.size >= 1
}
puts d.size
puts d.join " "


def read_next_line
  gets.chomp.split.map(&:to_i)
end

n, v = read_next_line
a = []
(1..n).each { |i|
  a << i if read_next_line[1..-1].any? { |x| x < v }
}
puts a.size
puts a * ' '


n, v = map(int, raw_input().split())
l = list()

for i in range(n):
        if min(map(int, raw_input().split()[1:])) < v:
                l.append(i + 1)

print len(l)
for x in l: print x,


n=raw_input()
n=list(n.split())
n=map(int,n)
v=n[1]
c=n[0]
count=1
r=[]
for i in range(c):
    sp=raw_input()
    sp=list(sp.split())
    sp=map(int,sp[1:])
    sp+=[v]
    sp.sort()
    if sp[0]<v:
        r+=[count]
    count+=1
if r:
    for i in r:
        print i,
else:
    print 0


n=raw_input()
n=list(n.split())
n=map(int,n)
v=n[1]
c=n[0]
k=0
count=1
r=[]
for i in range(c):
    sp=raw_input()
    sp=list(sp.split())
    sp=map(int,sp[1:])
    sp+=[v]
    sp.sort()
    if sp[0]<v:
        r+=[count]
        k+=1
    count+=1
print k
if r:
    for i in r:
        print i,
else:
    print 0


n=raw_input()
n=list(n.split())
n=map(int,n)
v=n[1]
c=n[0]
k=0
count=1
r=[]
for i in range(c):
    sp=raw_input()
    sp=list(sp.split())
    sp=map(int,sp[1:])
    sp+=[v]
    sp.sort()
    if sp[0]<v:
        r+=[count]
        k+=1
    count+=1
print k
if k!=0:
    if r:
        for i in r:
            print i,


n=raw_input()
n=list(n.split())
n=map(int,n)
v=n[1]
c=n[0]
count=1
r=[]
for i in range(c):
    sp=raw_input()
    sp=list(sp.split())
    sp=map(int,sp[1:])
    sp+=[v]
    sp.sort()
    if sp[1]<v:
        r+=[count]
    count+=1
if r:
    for i in r:
        print i,
else:
    print 0


n, v = map(int, raw_input().split())
ans=0
arr=[]
for i in xrange(n):
    li=map(int, raw_input().split())
    for j in li[1:]:
        if j<v:
            ans+=1
            arr.append(i+1)
            break
print ans
for i in arr:
    print i,


n, v = map(int, raw_input().split())
ans=0
arr=[]
for i in xrange(n):
    li=map(int, raw_input().split())
    for j in li[1:]:
        if j<v:
            ans+=1
            arr.append(i+1)
        break
print ans
for i in arr:
    print i,


nSellers,money=map(int,raw_input().split())
list=[]
for i in range(nSellers):
    items=map(int,raw_input().split())
    items.pop(0)
    for item in items:
        if(item<money):
            list.append(i+1)
            break
print len(list)
for seller in list:
    print seller,


l = raw_input().split()
n, v = int(l[0]), int(l[1])
ans = []
for i in range(n):
    l = raw_input().split()
    k, l2 = int(l[0]), l[1:]
    l2 = [int(j) for j in l2]
    for t in range(len(l2)):
        if l2[t] < v:
            ans.append(i+1)
            break
print len(ans)
for i in range(len(ans)):
    print ans[i],


l = raw_input().split()
n, v = int(l[0]), int(l[1])
ans = []
for i in range(n):
    l = raw_input().split()
    l2 = []
    k, l2 = int(l[0]), l[1:]
    l2 = [int(j) for j in l2]
    for t in range(len(l2)):
        if l2[t] < v:
            ans.append(i+1)
            continue
print len(ans)
for i in range(len(ans)):
    print ans[i],


l = raw_input().split()
n, v = int(l[0]), int(l[1])
ans = []
for i in range(n):
    l = raw_input().split()
    k, l2 = int(l[0]), l[1:]
    l2 = [int(j) for j in l2]
    for t in range(len(l2)):
        if l2[t] < v:
            ans.append(k)
            continue
print len(ans)
for i in range(len(ans)):
    print ans[i],


n, v = map(int, raw_input().split(" "))
a = []
for i in range(n):
	for j in filter(lambda x: x > 50, map(int, raw_input().split(" "))):
		if v > j:
			a.append(str(i+1))
print len(a)
print ' '.join(a)


n, v = map(int, raw_input().split(" "))
a = []
for i in range(n):
	for j in filter(lambda x: x > 50, map(int, raw_input().split(" "))):
		if v > j:
			a.append(str(i+1))
			break
print len(a)
print ' '.join(a)


n, v = map(int, raw_input().split())
result = []
for i in range(1, n+1):
				x = map(int, raw_input().split())
				for j in range (1, len(x)):
								if (v > x[j] and i not in result):
												result.append(i)
if (len(result) == 0):
				print 0
else:
				print len(result)
				print ' '.join(str(t) for t in result)


n, v = map(int, raw_input().split())
result = []
for i in range(1, n+1):
				x = map(int, raw_input().split())
				for j in range (1, len(x)):
								if (v > x[j]):
												result.append(i)
if (len(result) == 0):
				print 0
else:
				print len(result)
				print ' '.join(str(t) for t in result)


n, v = map(int, raw_input().split())
result = []
for i in range(1, n+1):
				x = map(int, raw_input().split())
				for j in range (1, len(x)):
								if (v > x[j]):
												result.append(i)
if (len(result) == 0):
				print 0
else:
				print len(result)
				print ', '.join(str(t) for t in result)


n, money = [int(c) for c in raw_input().strip().split()]
ar = [[int(c) for c in raw_input().strip().split()] for i in xrange(n)]
ar2 = []
for i in xrange(n):
	if min(ar[i][1:]) < money:
		ar2.append(i)
print len(ar2)
for x in ar2:
	print x,
print ''


n, money = [int(c) for c in raw_input().strip().split()]
ar = [[int(c) for c in raw_input().strip().split()] for i in xrange(n)]
ar2 = []
for i in xrange(n):
	if min(ar[i][1:]) < money:
		ar2.append(i)
print len(ar2)
for x in ar2:
	print x+1,
print ''


R = lambda: map(int, raw_input().split())
n, v = R()
ans = []
for i in range(n):
	if any(x <= v for x in R()):
		ans += [i + 1]
print str(len(ans)) + '\n' +  ' '.join(map(str, ans))


R = lambda: map(int, raw_input().split())
(n, v), a= R(), []
for i in range(n):
	if any(x < v for x in R()[1:]): a += [i + 1]
print str(len(a)) + '\n' +  ' '.join(map(str, a))


R = lambda: map(int, raw_input().split())
n, v = R()
ans = []
for i in range(n):
	if any(x < v for x in R()):
		ans += [i + 1]
print str(len(ans)) + '\n' +  ' '.join(map(str, ans))


string = raw_input().split(' ')
string = map(lambda x:int(x),string)
array = []
ans = []
for i in range(string[0]):
	temp = raw_input().split(' ')
	temp = map(lambda x:int(x),temp)
	array.append(temp)
for v in array:
	for i in range(1,v[0]+1):
		if(v[i]<string[1]):
			ans.append(array.index(v)+1)

print len(ans)
ans = map(str,ans)
print " ".join(ans)


string = raw_input().split(' ')
string = map(lambda x:int(x),string)
array = []
ans = []
for i in range(string[0]):
	temp = raw_input().split(' ')
	temp = map(lambda x:int(x),temp)
	array.append(temp)
for v in array:
	for i in range(1,v[0]+1):
		if(v[i]<string[1]):
			ans.append(array.index(v)+1)

ans = set(ans)
print len(set(ans))
ans = map(str,ans)
print " ".join(ans)


string = raw_input().split(' ')
string = map(lambda x:int(x),string)
array = []
ans = []
for i in range(string[0]):
	temp = raw_input().split(' ')
	temp = map(lambda x:int(x),temp)
	array.append(temp)
for v in array:
	for i in range(1,v[0]+1):
		if(v[i]<string[1]):
			ans.append(array.index(v)+1)

ans = sorted(set(ans))
print len(set(ans))
ans = map(str,ans)
print " ".join(ans)


n,v = map(int , raw_input().split())
i = 0
li = []
while(i < n):
    x = map(int , raw_input().split())
    li.append(x)
    i+=1
new = []
i = 0
while(i < n):
    if(min(li[i][1::]) < v):
        new.append(i+1)
    i+=1
if(new == []):
    print 0
else:
    print len(new)
    for a in new:
        print a,


n, mon = map(int, raw_input().strip().split())

itog = []
for i in range(n):
    pr = map(int, raw_input().strip().split())
    q = pr[0]
    pr = pr[1:]
    mini = min(pr)
    if mini < mon:
        itog.append(i+1)

if itog != []:
    itog = sorted(itog)
    print ' '.join(str(x) for x in itog)
else:
    print 0


n, mon = map(int, raw_input().strip().split())

itog = {}
for i in range(n):
    pr = map(int, raw_input().strip().split())
    q = pr[0]
    pr = pr[1:]
    mini = min(pr)
    if mini < mon:
        itog[mini] = i+1

if itog != {}:
    itogkeys = sorted(itog, reverse = True)
    print len(itogkeys)
    print ' '.join(str(itog[x]) for x in itogkeys)
else:
    print 0


n, mon = map(int, raw_input().strip().split())

itog = []
for i in range(n):
    pr = map(int, raw_input().strip().split())
    q = pr[0]
    pr = pr[1:]
    mini = min(pr)
    if mini < mon:
        itog.append(i+1)

if itog != []:
    itog = sorted(itog)
    print len(itog)
    print ' '.join(str(x) for x in itog)
else:
    print 0


n, mon = map(int, raw_input().strip().split())

itog = {}
for i in range(n):
    pr = map(int, raw_input().strip().split())
    q = pr[0]
    pr = pr[1:]
    mini = min(pr)
    if mini < mon:
        itog[mini] = i+1

if itog != {}:
    itogkeys = sorted(itog, reverse = True)
    print ' '.join(str(itog[x]) for x in itogkeys)
else:
    print 0


c = 0
n = raw_input().split()
res = ""
for i in range(0,int(n[0])):
    a = raw_input().split()
    for k in range(1,len(a)+1):
        if int(a[k]) < int(n[1]):
            c += 1
            res += str(i+1) + " "
            break
print c
print res


c = 0
n = raw_input().split()
res = ""
for i in range(0,int(n[0])):
    a = raw_input().split()
    for k in range(1,int(a[0])+1):
        if int(a[k]) < int(n[1]):
            c += 1
            res += str(i+1) + " "
            break
print c
print res


n, p = map(int, raw_input().split())
l = []
l1 = []
for i in range(0, n):
    l.append(map(int, raw_input().split()))
for i in range(0, len(l)):
    for j in range(1, len(l[i])):
        if p > l[i][j]:
            l1.append(i+1)
print len(set(l1))
if l1 != []:
    for i in sorted(set(l1)):
        print i,


n, p = map(int, raw_input().split())
l = []
l1 = []
for i in range(0, n):
    l.append(map(int, raw_input().split()))
for i in l:
    for j in range(1, len(i)):
        if p > i[j]:
            l1.append(i[0])
print len(set(l1))
if l1 != []:
    for i in set(l1):
        print i,


n, p = map(int, raw_input().split())
l = []
l1 = []
for i in range(0, n):
    l.append(map(int, raw_input().split()))
for i in l:
    for j in range(1, len(i)):
        if p > i[j]:
            l1.append(i[0])
print len(set(l1))
if l1 != []:
    for i in sorted(set(l1)):
        print i,


n, p = map(int, raw_input().split())
l = []
l1 = []
for i in range(0, n):
    l.append(map(int, raw_input().split()))
sum1 = 0
for i in l:
    for j in range(1, len(i)):
        if p > i[j]:
            sum1 += 1
            l1.append(i[0])
print sum1
if l1 != []:
    for i in set(l1):
        print i,


n, p = map(int, raw_input().split())
l = []
l1 = []
for i in range(0, n):
    l.append(map(int, raw_input().split()))
print l
for i in l:
    for j in range(1, len(i)):
        if p > i[j]:
            l1.append(i[0])
print len(set(l1))
if l1 != []:
    for i in sorted(set(l1)):
        print i,


vendors_and_budget = map(int, raw_input().split())
vendor_stock = []
fluent_vendor_list = []
for i in xrange(vendors_and_budget[0]):
    vendor_stock.append(map(int, raw_input().split()))
for k in  xrange(len(vendor_stock)):
    if min(vendor_stock[k][1::]) < vendors_and_budget[1]:
        fluent_vendor_list.append(vendor_stock[k][0])
a = len(fluent_vendor_list)
print a
print ' '.join(map(str, fluent_vendor_list))


vendors_and_budget = map(int, raw_input().split())
vendor_stock = []
fluent_vendor_list = []
for i in xrange(vendors_and_budget[0]):
    vendor_stock.append(map(int, raw_input().split()))
for k in  xrange(len(vendor_stock)):
    if vendor_stock[k][1] < vendors_and_budget[1]:
        fluent_vendor_list.append(vendor_stock[k][0])
a = len(fluent_vendor_list)
print a
print fluent_vendor_list


vendors_and_budget = map(int, raw_input().split())
vendor_stock = []
fluent_vendor_list = []
for i in xrange(vendors_and_budget[0]):
    vendor_stock.append(map(int, raw_input().split()))
for k in  xrange(len(vendor_stock)):
    if vendor_stock[k][1] < vendors_and_budget[1]:
        fluent_vendor_list.append(vendor_stock[k][0])
a = len(fluent_vendor_list)
print a
print ' '.join(map(str, fluent_vendor_list))


vendors_and_budget = map(int, raw_input().split())
vendor_stock = []
fluent_vendor_list = []
for i in xrange(vendors_and_budget[0]):
    vendor_stock.append(map(int, raw_input().split()))
for k in  xrange(len(vendor_stock)):
    if min(vendor_stock[k][1::]) < vendors_and_budget[1]:
        fluent_vendor_list.append(k+1)
a = len(fluent_vendor_list)
print a
print ' '.join(map(str, fluent_vendor_list))


# your code goes here
from sys import stdin
ar=map(int, stdin.readline().strip().split())
n=ar[0]
v=ar[1]

lt=list()
for i in xrange(n):
  ar=map(int, stdin.readline().strip().split())
  x=ar[0]
  for j in xrange(1, len(ar)):
    if ar[j]<v:
      lt.append(x)
if len(lt)>0:
  print len(lt)
  s=''
  for i in lt:
    s+=str(i)+' '
  print s.strip()
else:
  print 0


# your code goes here
from sys import stdin
ar=map(int, stdin.readline().strip().split())
n=ar[0]
v=ar[1]

lt=list()
for i in xrange(n):
  ar=map(int, stdin.readline().strip().split())
  x=ar[0]
  for j in xrange(1, len(ar)):
    if ar[j]<v:
      lt.append(i+1)
      break
if len(lt)>0:
  print len(lt)
  s=''
  for i in lt:
    s+=str(i)+' '
  print s.strip()
else:
  print 0


n,v = map(int,raw_input().split())
a = [sorted(map(int,raw_input().split())[1:]) for i in range(n)]
l = []
for i in range(n):
    if(v>a[i][0]):
        l.append(i+1)
print l.__len__()
print ' '.join(map(str,l))


n,v = map(int,raw_input().split())
a = [sorted(map(int,raw_input().split())[1:]) for i in range(n)]
print a
l = []
for i in range(n):
    if(v>a[i][0]):
        l.append(i+1)
print l.__len__()
print ' '.join(map(str,l))


n,v = map(int,raw_input().split())
ans = []
cnt = 0
for i in range(n):
    t = map(int,raw_input().split())
    a = t[1:]

    f = 0
    for j in range(len(a)):
        if a[j] <v:
            cnt += 1
            ans.append(i+1)
            break
print cnt
for i in ans:
    print i,


n,v = map(int,raw_input().split())

cnt = 0
for i in range(n):
    t = map(int,raw_input().split())
    a = t[1:]

    f = 0
    for i in a:
        if i <v:
            cnt += 1
            break
print cnt


n,v=map(int,raw_input().split())

sellers=[]

for i in range(n):
    inputs=raw_input().split()
    k=int(inputs[0])
    for j in inputs[1:]:
        if v>int(j):
            sellers.append(i+1)
            break

sellers.sort()
sellers_list=''

for i in sellers:
    sellers_list += str(i) + ' '

print len(sellers)
print sellers_list


n,v=map(int,raw_input().split())

sellers=[]

for i in range(n):
    inputs=raw_input().split()
    k=int(inputs[0])
    for j in inputs[1:]:
        if v>int(j):
            sellers.append(k)
            break

sellers.sort()
sellers_list=''

for i in sellers:
    sellers_list += str(i) + ' '

print len(sellers)
print sellers_list