import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class G {
	static int MOD = 1000000007;
	public static void main(String[] args) throws Exception {
		InputReader scan = new InputReader(new BufferedInputStream(System.in));
		int n = scan.nextInt(), k = scan.nextInt();
		Node[] arr = new Node[n];
		for(int i=0;i<n;i++)arr[i]=new Node();
		for (int i=0;i<n-1;i++) {
			int s = scan.nextInt() - 1, v = scan.nextInt() - 1, color = scan.nextInt();
			if (color == 0) {
				arr[s].adjacentNodes.add(arr[v]);
				arr[v].adjacentNodes.add(arr[s]);
			}
		}
		List<Integer> nodeGroups = dfs(arr);
		long ans=0L;
		for (Integer key: nodeGroups) {
			ans = Math.floorMod(ans+pow(key, k), MOD);
		}
		ans = Math.floorMod((pow(n, k) - ans),MOD);
		if (ans<0)ans+=MOD;
		System.out.println(ans);
		scan.close();
	}

	private static List<Integer> dfs(Node[] arr) {

		List<Integer> nodes = new LinkedList<>();
		for (int i=0;i<arr.length;i++) {
			if (!arr[i].visited)
				nodes.add(dfs(arr[i]));

		}
		//System.out.println(nodes);
		return nodes;
	}

	private static Integer dfs(Node node) {
		//List<Node> nodes = new LinkedList<>();
		//nodes.add(node);
		int ans = 1;
		node.visited=true;
		for (Node n: node.adjacentNodes) {
			if (!n.visited)
				ans += dfs(n);
		}
		return ans;
	}

	static class Node {
		int key;boolean visited=false;
		List<Node> adjacentNodes = new LinkedList<G.Node>();
	}

	private static long pow(int base, int exponent) {
		if (base==1)return 1l;
		if (exponent==1)return (long)base;
		if (exponent==0)return 1l;
		if (exponent%2==0) {
			long ans = pow(base,exponent/2);
			return Math.floorMod((ans*ans),MOD);
		}
		return Math.floorMod(((long)base*(long)pow(base,exponent-1)),MOD);
/*		long result = 1;
		base = base % MOD;
		while (exponent > 0) {
			if (exponent % 2 == 1) {
				result = result * base;
				result %= MOD;
			}
			exponent = exponent / 2;
			base = (base * base) % MOD;
		}
		return result;*/
	}

	static class UF {

		private int[] parent;  // parent[i] = parent of i
		private byte[] rank;   // rank[i] = rank of subtree rooted at i (never more than 31)
		private int count;     // number of components

		public UF(int n) {
			if (n < 0) throw new IllegalArgumentException();
			count = n;
			parent = new int[n];
			rank = new byte[n];
			for (int i = 0; i < n; i++) {
				parent[i] = i;
				rank[i] = 0;
			}
		}

		public Map<Integer, Integer> getCounts() {
			Map<Integer, Integer> map = new HashMap<>(count);
			for (int i:parent)
				map.put(i, 1+map.getOrDefault(i, 0));
			return map;
		}

		public void print() {
			System.out.println(Arrays.toString(parent));
			System.out.println(Arrays.toString(rank));
		}

		public int find(int p) {
			while (p != parent[p]) {
				parent[p] = parent[parent[p]];    // path compression by halving
				p = parent[p];
			}
			return p;
		}

		public int count() {
			return count;
		}

		public boolean connected(int p, int q) {
			return find(p) == find(q);
		}

		public void union(int p, int q) {
			int rootP = find(p);
			int rootQ = find(q);
			if (rootP == rootQ) return;
			// make root of smaller rank point to root of larger rank
			if      (rank[rootP] < rank[rootQ]) parent[rootP] = rootQ;
			else if (rank[rootP] > rank[rootQ]) parent[rootQ] = rootP;
			else {
				parent[rootQ] = rootP;

				rank[rootP]++;
			}
			count--;
		}
	}

	static class InputReader {

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public void close() throws IOException {
			this.stream.close();
		}

		public static boolean isWhitespace(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return isWhitespace(c);
		}

		public interface SpaceCharFilter {

			public boolean isSpaceChar(int ch);
		}

		public String next() {
			return nextString();
		}

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

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

		public Long nextLong() {
			return Long.parseLong(nextString());
		}

		public Double nextDouble() {
			return Double.parseDouble(nextString());
		}

		public char nextCharacter() {
			return nextString().charAt(0);
		}

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

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

		public double[] nextDoubleArray(int N) {
			double A[] = new double[N];
			for (int i = 0; i < N; i++) {
				A[i] = nextDouble();
			}
			return A;
		}
	}

	int min(int... a) {
		int min = Integer.MAX_VALUE;
		for (int v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	long min(long... a) {
		long min = Long.MAX_VALUE;
		for (long v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	double min(double... a) {
		double min = Double.MAX_VALUE;
		for (double v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	int max(int... a) {
		int max = Integer.MIN_VALUE;
		for (int v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	long max(long... a) {
		long max = Long.MIN_VALUE;
		for (long v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	double max(double... a) {
		double max = Double.MIN_VALUE;
		for (double v : a) {
			max = Math.max(max, v);
		}
		return max;
	}
}


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Map;
import java.util.Map.Entry;

public class C {
	static int MOD = 1000000007;
	public static void main(String[] args) throws Exception {
		InputReader scan = new InputReader(new BufferedInputStream(System.in));
		int n = scan.nextInt(), k = scan.nextInt();
		UF uf = new UF(n);
		for (int i=0;i<n-1;i++) {
			int s = scan.nextInt() - 1, v = scan.nextInt() - 1, color = scan.nextInt();
			if (color == 0)
				uf.union(s, v);
		}
		//uf.print();
		Map<Integer, Integer> counts = uf.getCounts();
		//System.out.println(counts);
		long ans=0L;
		for (Entry<Integer, Integer> key: counts.entrySet()) {
			ans = Math.floorMod(ans+pow(key.getValue(), k), MOD);
		}
		ans = Math.floorMod((pow(n, k) - ans),MOD);
		if (ans<0)ans+=MOD;
		System.out.println(ans);
		scan.close();
	}

	private static long pow(int n, int k) {
		if (k==1)return (long)n;
		if (k==0)return 1l;
		return Math.floorMod(((long)n*(long)pow(n,k-1)),MOD);
	}

	static class UF {

		private int[] parent;  // parent[i] = parent of i
		private byte[] rank;   // rank[i] = rank of subtree rooted at i (never more than 31)
		private int count;     // number of components

		public UF(int n) {
			if (n < 0) throw new IllegalArgumentException();
			count = n;
			parent = new int[n];
			rank = new byte[n];
			for (int i = 0; i < n; i++) {
				parent[i] = i;
				rank[i] = 0;
			}
		}

		public Map<Integer, Integer> getCounts() {
			Map<Integer, Integer> map = new HashMap<>();
			for (int i:parent)
				map.put(i, 1+map.getOrDefault(i, 0));
			return map;
		}

		public void print() {
			System.out.println(Arrays.toString(parent));
		}

		public int find(int p) {
			while (p != parent[p]) {
				parent[p] = parent[parent[p]];    // path compression by halving
				p = parent[p];
			}
			return p;
		}

		public int count() {
			return count;
		}

		public boolean connected(int p, int q) {
			return find(p) == find(q);
		}

		public void union(int p, int q) {
			int rootP = find(p);
			int rootQ = find(q);
			if (rootP == rootQ) return;
			// make root of smaller rank point to root of larger rank
			if      (rank[rootP] < rank[rootQ]) parent[rootP] = rootQ;
			else if (rank[rootP] > rank[rootQ]) parent[rootQ] = rootP;
			else {
				parent[rootQ] = rootP;

				rank[rootP]++;
			}
			count--;
		}
	}

	static class InputReader {

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public void close() throws IOException {
			this.stream.close();
		}

		public static boolean isWhitespace(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return isWhitespace(c);
		}

		public interface SpaceCharFilter {

			public boolean isSpaceChar(int ch);
		}

		public String next() {
			return nextString();
		}

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

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

		public Long nextLong() {
			return Long.parseLong(nextString());
		}

		public Double nextDouble() {
			return Double.parseDouble(nextString());
		}

		public char nextCharacter() {
			return nextString().charAt(0);
		}

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

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

		public double[] nextDoubleArray(int N) {
			double A[] = new double[N];
			for (int i = 0; i < N; i++) {
				A[i] = nextDouble();
			}
			return A;
		}
	}

	int min(int... a) {
		int min = Integer.MAX_VALUE;
		for (int v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	long min(long... a) {
		long min = Long.MAX_VALUE;
		for (long v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	double min(double... a) {
		double min = Double.MAX_VALUE;
		for (double v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	int max(int... a) {
		int max = Integer.MIN_VALUE;
		for (int v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	long max(long... a) {
		long max = Long.MIN_VALUE;
		for (long v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	double max(double... a) {
		double max = Double.MIN_VALUE;
		for (double v : a) {
			max = Math.max(max, v);
		}
		return max;
	}
}


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Map;
import java.util.Map.Entry;

public class C {
	static int MOD = 1000000007;
	public static void main(String[] args) throws Exception {
		InputReader scan = new InputReader(new BufferedInputStream(System.in));
		int n = scan.nextInt(), k = scan.nextInt();
		UF uf = new UF(n);
		for (int i=0;i<n-1;i++) {
			int s = scan.nextInt() - 1, v = scan.nextInt() - 1, color = scan.nextInt();
			if (color == 0)
				uf.union(s, v);
		}
		//uf.print();
		Map<Integer, Integer> counts = uf.getCounts();
		//System.out.println(counts);
		long ans=0L;
		for (Entry<Integer, Integer> key: counts.entrySet()) {
			ans = (ans+pow(key.getValue(), k)) % MOD;
		}
		ans = pow(n, k) - ans;
		if (ans<0)ans+=MOD;
		System.out.println(ans);
		scan.close();
	}

	private static long pow(int n, int k) {
		if (k==1)return n;
		if (k==0)return 1;
		return (n*pow(n,k-1))%MOD;
	}

	static class UF {

		private int[] parent;  // parent[i] = parent of i
		private byte[] rank;   // rank[i] = rank of subtree rooted at i (never more than 31)
		private int count;     // number of components

		public UF(int n) {
			if (n < 0) throw new IllegalArgumentException();
			count = n;
			parent = new int[n];
			rank = new byte[n];
			for (int i = 0; i < n; i++) {
				parent[i] = i;
				rank[i] = 0;
			}
		}

		public Map<Integer, Integer> getCounts() {
			Map<Integer, Integer> map = new HashMap<>();
			for (int i:parent)
				map.put(i, 1+map.getOrDefault(i, 0));
			return map;
		}

		public void print() {
			System.out.println(Arrays.toString(parent));
		}

		public int find(int p) {
			while (p != parent[p]) {
				parent[p] = parent[parent[p]];    // path compression by halving
				p = parent[p];
			}
			return p;
		}

		public int count() {
			return count;
		}

		public boolean connected(int p, int q) {
			return find(p) == find(q);
		}

		public void union(int p, int q) {
			int rootP = find(p);
			int rootQ = find(q);
			if (rootP == rootQ) return;
			// make root of smaller rank point to root of larger rank
			if      (rank[rootP] < rank[rootQ]) parent[rootP] = rootQ;
			else if (rank[rootP] > rank[rootQ]) parent[rootQ] = rootP;
			else {
				parent[rootQ] = rootP;

				rank[rootP]++;
			}
			count--;
		}
	}

	static class InputReader {

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public void close() throws IOException {
			this.stream.close();
		}

		public static boolean isWhitespace(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return isWhitespace(c);
		}

		public interface SpaceCharFilter {

			public boolean isSpaceChar(int ch);
		}

		public String next() {
			return nextString();
		}

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

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

		public Long nextLong() {
			return Long.parseLong(nextString());
		}

		public Double nextDouble() {
			return Double.parseDouble(nextString());
		}

		public char nextCharacter() {
			return nextString().charAt(0);
		}

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

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

		public double[] nextDoubleArray(int N) {
			double A[] = new double[N];
			for (int i = 0; i < N; i++) {
				A[i] = nextDouble();
			}
			return A;
		}
	}

	int min(int... a) {
		int min = Integer.MAX_VALUE;
		for (int v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	long min(long... a) {
		long min = Long.MAX_VALUE;
		for (long v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	double min(double... a) {
		double min = Double.MAX_VALUE;
		for (double v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	int max(int... a) {
		int max = Integer.MIN_VALUE;
		for (int v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	long max(long... a) {
		long max = Long.MIN_VALUE;
		for (long v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	double max(double... a) {
		double max = Double.MIN_VALUE;
		for (double v : a) {
			max = Math.max(max, v);
		}
		return max;
	}
}


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Map;
import java.util.Map.Entry;

public class C {
	static int MOD = 1000000007;
	public static void main(String[] args) throws Exception {
		InputReader scan = new InputReader(new BufferedInputStream(System.in));
		int n = scan.nextInt(), k = scan.nextInt();
		UF uf = new UF(n);
		for (int i=0;i<n-1;i++) {
			int s = scan.nextInt() - 1, v = scan.nextInt() - 1, color = scan.nextInt();
			if (color == 0)
				uf.union(s, v);
		}
		Map<Integer, Integer> counts = uf.getCounts();
		long ans=0L;
		for (Entry<Integer, Integer> key: counts.entrySet()) {
			ans += pow(key.getValue(), k);
		}
		ans = pow(n, k) - ans;
		System.out.println(ans%MOD);
		scan.close();
	}

	private static long pow(int n, int k) {
		if (k==1)return n;
		if (k==0)return 1;
		return (n*pow(n,k-1))%MOD;
	}

	static class UF {

		private int[] parent;  // parent[i] = parent of i
		private byte[] rank;   // rank[i] = rank of subtree rooted at i (never more than 31)
		private int count;     // number of components

		public UF(int n) {
			if (n < 0) throw new IllegalArgumentException();
			count = n;
			parent = new int[n];
			rank = new byte[n];
			for (int i = 0; i < n; i++) {
				parent[i] = i;
				rank[i] = 0;
			}
		}

		public Map<Integer, Integer> getCounts() {
			Map<Integer, Integer> map = new HashMap<>();
			for (int i:parent)
				map.put(i, 1+map.getOrDefault(i, 0));
			return map;
		}

		public void print() {
			System.out.println(Arrays.toString(parent));
		}

		public int find(int p) {
			while (p != parent[p]) {
				parent[p] = parent[parent[p]];    // path compression by halving
				p = parent[p];
			}
			return p;
		}

		public int count() {
			return count;
		}

		public boolean connected(int p, int q) {
			return find(p) == find(q);
		}

		public void union(int p, int q) {
			int rootP = find(p);
			int rootQ = find(q);
			if (rootP == rootQ) return;
			// make root of smaller rank point to root of larger rank
			if      (rank[rootP] < rank[rootQ]) parent[rootP] = rootQ;
			else if (rank[rootP] > rank[rootQ]) parent[rootQ] = rootP;
			else {
				parent[rootQ] = rootP;

				rank[rootP]++;
			}
			count--;
		}
	}

	static class InputReader {

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public void close() throws IOException {
			this.stream.close();
		}

		public static boolean isWhitespace(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return isWhitespace(c);
		}

		public interface SpaceCharFilter {

			public boolean isSpaceChar(int ch);
		}

		public String next() {
			return nextString();
		}

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

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

		public Long nextLong() {
			return Long.parseLong(nextString());
		}

		public Double nextDouble() {
			return Double.parseDouble(nextString());
		}

		public char nextCharacter() {
			return nextString().charAt(0);
		}

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

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

		public double[] nextDoubleArray(int N) {
			double A[] = new double[N];
			for (int i = 0; i < N; i++) {
				A[i] = nextDouble();
			}
			return A;
		}
	}

	int min(int... a) {
		int min = Integer.MAX_VALUE;
		for (int v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	long min(long... a) {
		long min = Long.MAX_VALUE;
		for (long v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	double min(double... a) {
		double min = Double.MAX_VALUE;
		for (double v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	int max(int... a) {
		int max = Integer.MIN_VALUE;
		for (int v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	long max(long... a) {
		long max = Long.MIN_VALUE;
		for (long v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	double max(double... a) {
		double max = Double.MIN_VALUE;
		for (double v : a) {
			max = Math.max(max, v);
		}
		return max;
	}
}


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Map;
import java.util.Map.Entry;

public class C {
	static int MOD = 1000000007;
	public static void main(String[] args) throws Exception {
		InputReader scan = new InputReader(new BufferedInputStream(System.in));
		int n = scan.nextInt(), k = scan.nextInt();
		UF uf = new UF(n);
		for (int i=0;i<n-1;i++) {
			int s = scan.nextInt() - 1, v = scan.nextInt() - 1, color = scan.nextInt();
			if (color == 0)
				uf.union(s, v);
		}
		//uf.print();
		Map<Integer, Integer> counts = uf.getCounts();
		//System.out.println(counts);
		long ans=0L;
		for (Entry<Integer, Integer> key: counts.entrySet()) {
			ans = (ans+pow(key.getValue(), k)) % MOD;
		}
		ans = pow(n, k) - ans;
		if (ans<0)ans+=MOD;
		System.out.println(ans);
		scan.close();
	}

	private static long pow(int n, int k) {
		if (k==1)return (long)n;
		if (k==0)return 1l;
		return ((long)n*(long)pow(n,k-1))%MOD;
	}

	static class UF {

		private int[] parent;  // parent[i] = parent of i
		private byte[] rank;   // rank[i] = rank of subtree rooted at i (never more than 31)
		private int count;     // number of components

		public UF(int n) {
			if (n < 0) throw new IllegalArgumentException();
			count = n;
			parent = new int[n];
			rank = new byte[n];
			for (int i = 0; i < n; i++) {
				parent[i] = i;
				rank[i] = 0;
			}
		}

		public Map<Integer, Integer> getCounts() {
			Map<Integer, Integer> map = new HashMap<>();
			for (int i:parent)
				map.put(i, 1+map.getOrDefault(i, 0));
			return map;
		}

		public void print() {
			System.out.println(Arrays.toString(parent));
		}

		public int find(int p) {
			while (p != parent[p]) {
				parent[p] = parent[parent[p]];    // path compression by halving
				p = parent[p];
			}
			return p;
		}

		public int count() {
			return count;
		}

		public boolean connected(int p, int q) {
			return find(p) == find(q);
		}

		public void union(int p, int q) {
			int rootP = find(p);
			int rootQ = find(q);
			if (rootP == rootQ) return;
			// make root of smaller rank point to root of larger rank
			if      (rank[rootP] < rank[rootQ]) parent[rootP] = rootQ;
			else if (rank[rootP] > rank[rootQ]) parent[rootQ] = rootP;
			else {
				parent[rootQ] = rootP;

				rank[rootP]++;
			}
			count--;
		}
	}

	static class InputReader {

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public void close() throws IOException {
			this.stream.close();
		}

		public static boolean isWhitespace(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public int read() {
			if (numChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0) {
					return -1;
				}
			}
			return buf[curChar++];
		}

		public boolean isSpaceChar(int c) {
			if (filter != null) {
				return filter.isSpaceChar(c);
			}
			return isWhitespace(c);
		}

		public interface SpaceCharFilter {

			public boolean isSpaceChar(int ch);
		}

		public String next() {
			return nextString();
		}

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

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

		public Long nextLong() {
			return Long.parseLong(nextString());
		}

		public Double nextDouble() {
			return Double.parseDouble(nextString());
		}

		public char nextCharacter() {
			return nextString().charAt(0);
		}

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

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

		public double[] nextDoubleArray(int N) {
			double A[] = new double[N];
			for (int i = 0; i < N; i++) {
				A[i] = nextDouble();
			}
			return A;
		}
	}

	int min(int... a) {
		int min = Integer.MAX_VALUE;
		for (int v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	long min(long... a) {
		long min = Long.MAX_VALUE;
		for (long v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	double min(double... a) {
		double min = Double.MAX_VALUE;
		for (double v : a) {
			min = Math.min(min, v);
		}
		return min;
	}

	int max(int... a) {
		int max = Integer.MIN_VALUE;
		for (int v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	long max(long... a) {
		long max = Long.MIN_VALUE;
		for (long v : a) {
			max = Math.max(max, v);
		}
		return max;
	}

	double max(double... a) {
		double max = Double.MIN_VALUE;
		for (double v : a) {
			max = Math.max(max, v);
		}
		return max;
	}
}


import java.util.*;
import java.io.*;
public class EdgyTrees548C {
	  static class FastReader {

	        BufferedReader br;
	        StringTokenizer st;

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

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

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

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

	static int mod = 1000000007;
	static HashMap<Integer,ArrayList<Integer>> adj = new HashMap<>();
	static boolean visited[];
	public static void main(String[] args) {
		FastReader s =new FastReader();
		int n = s.nextInt();
		int k = s.nextInt();
		for(int i=1;i<=n;i++) {
			adj.put(i, new ArrayList<>());
		}

		for(int i =1;i<n;i++) {
			int u = s.nextInt();
			int v = s.nextInt();
			int color=s.nextInt();

			if(color==0) {
				adj.get(u).add(v);
				adj.get(v).add(u);
			}
		}
		visited = new boolean [n+1];
		long nk = expo(n,k);
		for(int src=1;src<=n;src++) {
			int  p =0;
			if(!visited[src]) {
				visited[src] = true;
				 p = dfs(adj,src);
				// System.out.println(p);
				 //System.out.println(expo(p,k));
				 nk = (nk-expo(p,k))%mod;
				 }

		}
		System.out.println(nk);

	}
	private static long expo(long n, long k) {
		if(k==0)
			return 1;
		if(k==1) return n;

		if(k%2==0) {
			long y = expo(n, k/2)%mod;
			return (y*y)%mod;
		}
		return n*expo(n, k-1);
	}
	private static int dfs(HashMap<Integer, ArrayList<Integer>> adj,int src) {
		ArrayList<Integer> nbrs = adj.get(src);
		int kr =0;
		for(int nbr:nbrs) {
		if(!visited[nbr]) {
			visited[nbr] = true;
			kr +=  dfs(adj,nbr);
		}
		}
		return kr+1;
	}

}


import java.util.*;
import java.io.*;
public class EdgyTrees548C {
	  static class FastReader {

	        BufferedReader br;
	        StringTokenizer st;

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

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

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

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

	static int mod = 1000000007;
	static HashMap<Integer,ArrayList<Integer>> adj = new HashMap<>();
	static boolean visited[];
	public static void main(String[] args) {
		FastReader s =new FastReader();
		int n = s.nextInt();
		int k = s.nextInt();
		for(int i=1;i<=n;i++) {
			adj.put(i, new ArrayList<>());
		}

		for(int i =1;i<n;i++) {
			int u = s.nextInt();
			int v = s.nextInt();
			int color=s.nextInt();

			if(color==0) {
				adj.get(u).add(v);
				adj.get(v).add(u);
			}
		}
		visited = new boolean [n+1];
		int nk = expo(n,k);
		for(int src=1;src<=n;src++) {
			int  p =0;
			if(!visited[src]) {
				visited[src] = true;
				 p = dfs(adj,src);
				// System.out.println(p);
				 //System.out.println(expo(p,k));
				 nk = (nk-expo(p,k))%mod;
				 }

		}
		System.out.println(nk);

	}
	private static int expo(int n, int k) {
		if(k==0)
			return 1;
		if(k==1) return n;

		if(k%2==0) {
			int y = expo(n, k/2)%mod;
			return (y*y)%mod;
		}
		return n*expo(n, k-1);
	}
	private static int dfs(HashMap<Integer, ArrayList<Integer>> adj,int src) {
		ArrayList<Integer> nbrs = adj.get(src);
		int kr =0;
		for(int nbr:nbrs) {
		if(!visited[nbr]) {
			visited[nbr] = true;
			kr +=  dfs(adj,nbr);
		}
		}
		return kr+1;
	}

}


import java.util.*;
import java.io.*;
public class EdgyTrees548C {
	  static class FastReader {

	        BufferedReader br;
	        StringTokenizer st;

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

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

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

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

	static int mod = 1000000007;
	static HashMap<Integer,ArrayList<Integer>> adj = new HashMap<>();
	static boolean visited[];
	public static void main(String[] args) {
		FastReader s =new FastReader();
		int n = s.nextInt();
		int k = s.nextInt();
		for(int i=1;i<=n;i++) {
			adj.put(i, new ArrayList<>());
		}

		for(int i =1;i<n;i++) {
			int u = s.nextInt();
			int v = s.nextInt();
			int color=s.nextInt();

			if(color==0) {
				adj.get(u).add(v);
				adj.get(v).add(u);
			}
		}
		visited = new boolean [n+1];
		long nk = (expo(n,k)%mod);
		//System.out.println(nk);
		long np = 0;
		for(int src=1;src<=n;src++) {
			int  p =0;
			if(!visited[src]) {
				visited[src] = true;
				 p = dfs(adj,src);
				// System.out.println(p);
				 //System.out.println(expo(p,k));
				 np = ((np%mod)+(expo(p,k)%mod))%mod;
				 //System.out.println(np);
			}

		}
		System.out.println(((nk%mod)-(np%mod)+mod)%mod);

	}
	private static long expo(long n, long k) {
		if(k==0)
			return 1L;
		if(k==1) return n;

		if(k%2==0) {
			long y = expo(n, k/2)%mod;
			return (y*y)%mod;
		}
		return ((n%mod)*(expo(n, k-1))%mod)%mod;
	}
	private static int dfs(HashMap<Integer, ArrayList<Integer>> adj,int src) {
		ArrayList<Integer> nbrs = adj.get(src);
		int kr =0;
		for(int nbr:nbrs) {
		if(!visited[nbr]) {
			visited[nbr] = true;
			kr +=  dfs(adj,nbr);
		}
		}
		return kr+1;
	}

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[setJ] = setI;
			size[setI] += size[setJ];
		} else {
			parents[setI] = setJ;
			size[setJ] += size[setI];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		BigInteger res = BigInteger.valueOf(numNodes);
		res=res.pow(length);

		//System.out.println(res);
		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				int src =Integer.parseInt(edge[0])-1;
				int dest = Integer.parseInt(edge[1])-1;
				union(parents, size,src,dest);

			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				BigInteger ccComb = BigInteger.valueOf(size[i]);
				ccComb=ccComb.pow(length);
				res=res.subtract(ccComb);
				BigInteger mod = BigInteger.valueOf(1000000007);
				res=res.mod(mod);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static int union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return -1;

		if (size[setI] >= size[setJ]) {
			parents[j] = i;
			size[i] += size[j];
			return size[i];
		} else {
			parents[i] = j;
			size[j] += size[i];
			return size[j];
		}
		return -1;
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				int src =Integer.parseInt(edge[0])-1;
				int dest = Integer.parseInt(edge[1])-1;
				if(numNodes==13) {
					System.out.println("union " + (src+1) + " " + (dest+1));
				}

				int newSize = union(parents, size,src,dest);
				if(numNodes == 13)
					System.out.println("new size " + newSize);

			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				if(numNodes==13) {
					System.out.println(size[i] + " " + (i+1));

				}

				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static int union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return -1;

		if (size[setI] >= size[setJ]) {
			parents[setJ] = setI;
			size[setI] += size[setJ];
			return size[setI];
		} else {
			parents[setI] = setJ;
			size[setJ] += size[setI];
			return size[setJ];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				int src =Integer.parseInt(edge[0])-1;
				int dest = Integer.parseInt(edge[1])-1;
				if(numNodes==13) {
					System.out.println("union " + (src+1) + " " + (dest+1));
				}

				int newSize = union(parents, size,src,dest);
				if(numNodes == 13)
					System.out.println("new size " + newSize);

			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				if(numNodes==13) {
					System.out.println(size[i] + " " + (i+1));

				}

				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[j] = i;
			size[i] += size[j];
		} else {
			parents[i] = j;
			size[j] += size[i];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				union(parents, size, Integer.parseInt(edge[0])-1, Integer.parseInt(edge[1])-1);
			}

		}
		for(int i=0;i<numNodes;i++) {
			if(find(parents,i)==i) {
				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[j] = i;
			size[i] += size[j];
		} else {
			parents[i] = j;
			size[j] += size[i];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				int src =Integer.parseInt(edge[0])-1;
				int dest = Integer.parseInt(edge[1])-1;
				if(numNodes==13) {
					System.out.println("union " + (src+1) + " " + (dest+1));
				}
				union(parents, size,src,dest);
			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				if(numNodes==13) {
					System.out.println(size[i] + " " + (i+1));

				}

				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[j] = i;
			size[i] += size[j];
		} else {
			parents[i] = j;
			size[j] += size[i];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				union(parents, size, Integer.parseInt(edge[0])-1, Integer.parseInt(edge[1])-1);
			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				if(numNodes==13) {
					System.out.println(size[i] + " " + (i+1));

				}

				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[setJ] = setI;
			size[setI] += size[setJ];
		} else {
			parents[setI] = setJ;
			size[setJ] += size[setI];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				int src =Integer.parseInt(edge[0])-1;
				int dest = Integer.parseInt(edge[1])-1;
				union(parents, size,src,dest);

			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[setJ] = setI;
			size[setI] += size[setJ];
		} else {
			parents[setI] = setJ;
			size[setJ] += size[setI];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				int src =Integer.parseInt(edge[0])-1;
				int dest = Integer.parseInt(edge[1])-1;
				union(parents, size,src,dest);

			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res % 1000000007);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[j] = i;
			size[i] += size[j];
		} else {
			parents[i] = j;
			size[j] += size[i];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				int src =Integer.parseInt(edge[0])-1;
				int dest = Integer.parseInt(edge[1])-1;
				if(numNodes==13) {
					System.out.println("union " + src + " " + dest);
				}
				union(parents, size,src,dest);
			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				if(numNodes==13) {
					System.out.println(size[i] + " " + (i+1));

				}

				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[j] = i;
			size[i] += size[j];
		} else {
			parents[i] = j;
			size[j] += size[i];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				union(parents, size, Integer.parseInt(edge[0])-1, Integer.parseInt(edge[1])-1);
			}

		}
		for(int i=0;i<numNodes;i++) {
			if(numNodes==13)
				System.out.println(size[i]);
			if(find(parents,i)==i) {
				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[j] = i;
			size[i] += size[j];
		} else {
			parents[i] = j;
			size[j] += size[i];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				union(parents, size, Integer.parseInt(edge[0])-1, Integer.parseInt(edge[1])-1);
			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				if(numNodes==13)
					System.out.println(size[i]);
				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static int union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return -1;

		if (size[setI] >= size[setJ]) {
			parents[j] = i;
			size[i] += size[j];
			return size[i];
		} else {
			parents[i] = j;
			size[j] += size[i];
			return size[j];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				int src =Integer.parseInt(edge[0])-1;
				int dest = Integer.parseInt(edge[1])-1;
				if(numNodes==13) {
					System.out.println("union " + (src+1) + " " + (dest+1));
				}

				int newSize = union(parents, size,src,dest);
				if(numNodes == 13)
					System.out.println("new size " + newSize);

			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				if(numNodes==13) {
					System.out.println(size[i] + " " + (i+1));

				}

				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res);

		in.close();

	}

}


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

public class Problem {

	static int find(int[] parents, int i) {
		if (parents[i] != i) {
			parents[i] = find(parents, parents[i]);
		}
		return parents[i];
	}

	static void union(int[] parents, int[] size, int i, int j) {
		int setI = find(parents, i);
		int setJ = find(parents, j);
		if (setI == setJ)
			return;

		if (size[setI] >= size[setJ]) {
			parents[setJ] = setI;
			size[setI] += size[setJ];
		} else {
			parents[setI] = setJ;
			size[setJ] += size[setI];
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] next = in.readLine().trim().split(" ");
		int numNodes = Integer.parseInt(next[0]);
		int length = Integer.parseInt(next[1]);
		int[] parents = new int[numNodes];
		int[] size = new int[numNodes];
		long res = (long) Math.pow((double) numNodes, (double) length);
		if(numNodes == 19 && length==20) {
			System.out.println(res);
		}

		for (int i = 0; i < numNodes; i++) {
			parents[i] = i;
			size[i] = 1;
		}
		for (int i = 0; i < numNodes - 1; i++) {
			String[] edge = in.readLine().trim().split(" ");
			if (edge[2].equals("0")) {
				int src =Integer.parseInt(edge[0])-1;
				int dest = Integer.parseInt(edge[1])-1;
				union(parents, size,src,dest);

			}

		}
		for(int i=0;i<numNodes;i++) {

			if(find(parents,i)==i) {
				res -= (long)Math.pow((double)size[i], (double)length);
			}
		}

		System.out.println(res % 1000000007);

		in.close();

	}

}


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

import static java.lang.System.out;

public class Main {

    private Scanner scanner = new Scanner(System.in);

    private int p[];
    private int size [];

    void make(int v) {
        p[v] = v;
        size[v] = 1;
    }

    private int find(int v) {
        if (v == p[v]) {
            return v;
        }
        return p[v] = find(p[v]);
    }

    private void union(int a, int b) {
        a = find(a);
        b = find(b);
        if (a != b) {
            if (size[a] < size[b]) {
                int t = b;
                b = a;
                a = t;
            }
            p[b] = a;
            size[a] += size[b];
        }
    }

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

    private void solve() {
        int n = scanner.nextInt(), k = scanner.nextInt();

        p = new int[n];
        size = new int[n];
        for (int i = 0; i < n; i++) {
            make(i);
        }

        for (int i = 0; i < n - 1; i++) {
            int u = scanner.nextInt() - 1, v = scanner.nextInt() - 1, c = scanner.nextInt();
            if (c == 0) {
                union(u, v);
            }
        }

        int ans = 1;
        for (int i = 0; i < k; i++) {
            ans = (ans * n) % 1000000007;
        }

        boolean used[] = new boolean[n];
        for (int i = 0; i < n; i++) {
            int t = find(i);
            if (! used[t]) {
                int sz = size[t];
                int bad = 1;
                for (int j = 0; j < k; j++) {
                    bad = bad * (sz) % 1000000007;
                }
                ans = ans - bad;
                used[t] = true;
            }
        }
        out.println(ans );
    }
}


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

import static java.lang.System.out;

public class Main {

    private Scanner scanner = new Scanner(System.in);

    private int p[];
    private int size [];

    void make(int v) {
        p[v] = v;
        size[v] = 1;
    }

    private int find(int v) {
        if (v == p[v]) {
            return v;
        }
        return p[v] = find(p[v]);
    }

    private void union(int a, int b) {
        a = find(a);
        b = find(b);
        if (a != b) {
            if (size[a] < size[b]) {
                int t = b;
                b = a;
                a = t;
            }
            p[b] = a;
            size[a] += size[b];
        }
    }

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

    private void solve() {
        int n = scanner.nextInt(), k = scanner.nextInt();

        p = new int[n];
        size = new int[n];
        for (int i = 0; i < n; i++) {
            make(i);
        }

        for (int i = 0; i < n - 1; i++) {
            int u = scanner.nextInt() - 1, v = scanner.nextInt() - 1, c = scanner.nextInt();
            if (c == 0) {
                union(u, v);
            }
        }

        long ans = 1;
        for (int i = 0; i < k; i++) {
            ans = (ans * n) % 1000000007;
        }

        boolean used[] = new boolean[n];
        for (int i = 0; i < n; i++) {
            int t = find(i);
            if (! used[t]) {
                int sz = size[t];
                long bad = 1;
                for (int j = 0; j < k; j++) {
                    bad = bad * (sz) % 1000000007;
                }
                ans = ans - bad;
                used[t] = true;
            }
        }
        out.println(ans );
    }
}


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

import static java.lang.System.out;

public class Main {

    private Scanner scanner = new Scanner(System.in);

    private int p[];
    private int size [];

    void make(int v) {
        p[v] = v;
        size[v] = 1;
    }

    private int find(int v) {
        if (v == p[v]) {
            return v;
        }
        return p[v] = find(p[v]);
    }

    private void union(int a, int b) {
        a = find(a);
        b = find(b);
        if (a != b) {
            if (size[a] < size[b]) {
                int t = b;
                b = a;
                a = t;
            }
            p[b] = a;
            size[a] += size[b];
        }
    }

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

    private void solve() {
        int n = scanner.nextInt(), k = scanner.nextInt();

        p = new int[n];
        size = new int[n];
        for (int i = 0; i < n; i++) {
            make(i);
        }

        for (int i = 0; i < n - 1; i++) {
            int u = scanner.nextInt() - 1, v = scanner.nextInt() - 1, c = scanner.nextInt();
            if (c == 0) {
                union(u, v);
            }
        }

        int ans = 1;
        for (int i = 0; i < k; i++) {
            ans *= n;
        }

        boolean used[] = new boolean[n];
        for (int i = 0; i < n; i++) {
            int t = find(i);
            if (! used[t]) {
                int sz = size[t];
                int bad = 1;
                for (int j = 0; j < k; j++) {
                    bad = bad * (sz) % 1000000007;
                }
                ans = (ans - bad) % 1000000007;
                used[t] = true;
            }
        }
        out.println(ans );
    }
}


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

import static java.lang.System.out;

public class Main {

    private Scanner scanner = new Scanner(System.in);

    private int p[];
    private int size [];

    void make(int v) {
        p[v] = v;
        size[v] = 1;
    }

    private int find(int v) {
        if (v == p[v]) {
            return v;
        }
        return p[v] = find(p[v]);
    }

    private void union(int a, int b) {
        a = find(a);
        b = find(b);
        if (a != b) {
            if (size[a] < size[b]) {
                int t = b;
                b = a;
                a = t;
            }
            p[b] = a;
            size[a] += size[b];
        }
    }

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

    private void solve() {
        int n = scanner.nextInt(), k = scanner.nextInt();

        p = new int[n];
        size = new int[n];
        for (int i = 0; i < n; i++) {
            make(i);
        }

        for (int i = 0; i < n - 1; i++) {
            int u = scanner.nextInt() - 1, v = scanner.nextInt() - 1, c = scanner.nextInt();
            if (c == 0) {
                union(u, v);
            }
        }

        long ans = 1;
        for (int i = 0; i < k; i++) {
            ans = (ans * n) % 1000000007;
        }

        boolean used[] = new boolean[n];
        long bad = 0;
        for (int i = 0; i < n; i++) {
            int t = find(i);
            if (! used[t]) {
                int sz = size[t];
                long b = 1;
                for (int j = 0; j < k; j++) {
                    b = b * (sz) % 1000000007;
                }
                bad = (bad + b) % 1000000007;
                used[t] = true;
            }
        }
        out.println((ans - bad + 1000000007) %  1000000007);
    }
}


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

public class TaskC {

	static int[][] graph;
	static long counter;
	static long mod = 1000000007;

	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		int n = in.nextInt();
		int k = in.nextInt();
		graph = new int[n][n];
		for (int i = 0; i < n-1; i++) {
			int u = in.nextInt()-1;
			int v = in.nextInt()-1;
			int x = in.nextInt();
			if(x == 0) {
				graph[u][v] = 1;
				graph[v][u] = 1;
			}
		}
		boolean[] visited = new boolean[n];
		long total = 0;
		long ans = fast_pow(n, k);
		for (int i = 0; i < n; i++) {
			if(!visited[i]) {
				counter = 0;
				dfs(i, visited);
				total += fast_pow(counter, k);
			}
		}
		total %= mod;
		ans = (ans - total + mod)%mod;
		out.println(ans);
		out.close();
	}

	static long fast_pow(long a, long b) {
		if(b == 0)
			return 1L;

		long val = fast_pow(a, b / 2);

		if(b % 2 == 0)
			return val * val % mod;
		else
			return val * val % mod * a % mod;
	}

	static void dfs(int v, boolean[] visited) {
		visited[v] = true;
		counter++;

		for (int i = 0; i < graph[v].length; i++) {
			if(!visited[i] && graph[v][i] == 1)
				dfs(i, visited);
		}
	}

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

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

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

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

	}

}


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

public class TaskC {

	static List<Integer>[] graph;
	static long counter;
	static long mod = 1000000007;

	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		int n = in.nextInt();
		int k = in.nextInt();
		graph = new ArrayList[n];
		for(int i = 0; i < n; ++i)
			graph[i] = new ArrayList<Integer>();
		for (int i = 0; i < n-1; i++) {
			int u = in.nextInt()-1;
			int v = in.nextInt()-1;
			int x = in.nextInt();
			if(x == 0) {
				graph[u].add(v);
				graph[v].add(u);
			}
		}
		boolean[] visited = new boolean[n];
		long total = 0;
		long ans = fast_pow(n, k);
		for (int i = 0; i < n; i++) {
			if(!visited[i]) {
				counter = 0;
				dfs(i, visited);
				total += fast_pow(counter, k);
			}
		}
		total %= mod;
		ans = (ans - total + mod)%mod;
		out.println(ans);
		out.close();
	}

	static long fast_pow(long a, long b) {
		if(b == 0)
			return 1L;

		long val = fast_pow(a, b / 2);

		if(b % 2 == 0)
			return val * val % mod;
		else
			return val * val % mod * a % mod;
	}

	static void dfs(int v, boolean[] visited) {
		visited[v] = true;
		counter++;

		for(int j : graph[v]) {
			if(!visited[j])
				dfs(j, visited);
		}

	}

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

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

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

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

	}

}


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

public class TaskC {

	static int[][] graph;
	static long counter;
	static long mod = 1000000007;

	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		int n = in.nextInt();
		int k = in.nextInt();
		graph = new int[n][n];
		for (int i = 0; i < n-1; i++) {
			int u = in.nextInt()-1;
			int v = in.nextInt()-1;
			int x = in.nextInt();
			if(x == 0) {
				graph[u][v] = 1;
				graph[v][u] = 1;
			}
		}
		boolean[] visited = new boolean[n];
		long total = 0;
		for (int i = 0; i < n; i++) {
			if(!visited[i]) {
				counter = 0;
				dfs(i, visited);
				counter %= mod;
				total += exponentMod(counter, k);
			}
		}
		total = exponentMod(n, k) - total;
		out.println(total);
		out.close();
	}

	static long exponentMod(long A, long B) {

		if (A == 0)
			return 0;
		if (B == 0)
			return 1;

		long y;
		if (B % 2 == 0){
			y = exponentMod(A, B / 2);
			y = (y * y) % mod;
		}
		else{
			y = A % mod;
			y = (y * exponentMod(A, B - 1) % mod) % mod;
		}

		return (long)((y + mod) % mod);
	}

	static void dfs(int v, boolean[] visited) {
		visited[v] = true;
		counter++;

		for (int i = 0; i < graph[v].length; i++) {
			if(!visited[i] && graph[v][i] == 1)
				dfs(i, visited);
		}
	}

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

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

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

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

	}

}


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

public class Solution {
	public static void main (String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] temp=br.readLine().trim().split(" ");
		int V=Integer.parseInt(temp[0]);
		int k=Integer.parseInt(temp[1]);

		DSU graph=new DSU(V);
		for(int i=1;i<V;i++)
		{
		    temp=br.readLine().trim().split(" ");
		    int u=Integer.parseInt(temp[0]);
		    int v=Integer.parseInt(temp[1]);
		    int color=Integer.parseInt(temp[2]);
		    if(color==0){
		        graph.makeUnion(u,v);
		    }
		}
		int notGoodSequences=0;
		int mod=1000000009;
		boolean[] marked=new boolean[V+1];
		for(int i=1;i<=V;i++){
		    int parent=graph.getParent(i);
		    if(marked[parent]==false){
		        marked[parent]=true;
		        int size=graph.componentSize(i);
		        notGoodSequences=(int)(0L+notGoodSequences+aPowerBModC(size,k,mod))%mod;
		    }
		}
		int ans=(aPowerBModC(V,k,mod)-notGoodSequences+mod)%mod;
		System.out.println(ans);
	}
	public static int aPowerBModC(int a,int b,int c){
	    if(b==0){
	        return 1;
	    }
	    int smallAns=aPowerBModC(a,b/2,c);
	    int ans=(int)(1L*smallAns*smallAns)%c;
	    if(b%2!=0){
	        ans=(int)(1L*ans*(a%c))%c;
	    }
	    return ans;
	}
}
class DSU{
    private int[] parent;
    private int[] size;

    public DSU(int V)
    {
        parent=new int[V+1];
        size=new int[V+1];
        for(int i=1;i<=V;i++)
        {
            parent[i]=i;
            size[i]=1;
        }
    }
    public int getParent(int vertex)
    {
        int temp=vertex;
        while(parent[vertex]!=vertex){
            vertex=parent[vertex];
        }
        parent[temp]=vertex;
        return vertex;
    }
    public void makeUnion(int u,int v){
        int parent1=getParent(u);
        int parent2=getParent(v);

        if(parent2==parent1)
        {
            return;
        }
        int size1=size[parent1];
        int size2=size[parent2];

        if(size2<size1){
            parent[parent2]=parent1;
            size[parent1]+=size[parent2];
        }
        else{
            parent[parent1]=parent2;
            size[parent2]+=size[parent1];
        }
    }
    public int numComponents(){
        int ans=0;
        int V=this.parent.length-1;
        for(int i=1;i<=V;i++){
            if(this.parent[i]==i){
                ans++;
            }
        }
        return ans;
    }
    public int componentSize(int vertex){
        int parent=getParent(vertex);
        return size[parent];
    }
}


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

public class Solution {
	public static void main (String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] temp=br.readLine().trim().split(" ");
		int V=Integer.parseInt(temp[0]);
		int k=Integer.parseInt(temp[1]);

		DSU graph=new DSU(V);
		for(int i=1;i<V;i++)
		{
		    temp=br.readLine().trim().split(" ");
		    int u=Integer.parseInt(temp[0]);
		    int v=Integer.parseInt(temp[1]);
		    int color=Integer.parseInt(temp[2]);
		    if(color==0){
		        graph.makeUnion(u,v);
		    }
		}
		long notGoodSequences=0;
		int mod=(int)(Math.pow(10,9)+7);
		boolean[] marked=new boolean[V+1];
		for(int i=1;i<=V;i++){
		    int parent=graph.getParent(i);
		    if(marked[parent]==false){
		        marked[parent]=true;
		        int size=graph.componentSize(i);
		        notGoodSequences=(notGoodSequences+aPowerBModC(size,k,mod))%mod;
		    }
		}
// 		System.out.println("total "+aPowerBModC(V,k,mod));
// 		System.out.println("not good "+notGoodSequences);
		long ans=(aPowerBModC(V,k,mod)-notGoodSequences+mod)%mod;
		System.out.println(ans);
	}
	public static long aPowerBModC(int a,int b,int c){
	    if(b==0){
	        return 1;
	    }
	    long smallAns=aPowerBModC(a,b/2,c);
	    long ans=(smallAns*smallAns)%c;
	    if(b%2!=0){
	        ans=(ans*(a%c))%c;
	    }
	    return ans;
	}
}
class DSU{
    private int[] parent;
    private int[] size;

    public DSU(int V)
    {
        parent=new int[V+1];
        size=new int[V+1];
        for(int i=1;i<=V;i++)
        {
            parent[i]=i;
            size[i]=1;
        }
    }
    public int getParent(int vertex)
    {
        int temp=vertex;
        while(parent[vertex]!=vertex){
            vertex=parent[vertex];
        }
        parent[temp]=vertex;
        return vertex;
    }
    public void makeUnion(int u,int v){
        int parent1=getParent(u);
        int parent2=getParent(v);

        if(parent2==parent1)
        {
            return;
        }
        int size1=size[parent1];
        int size2=size[parent2];

        if(size2<size1){
            parent[parent2]=parent1;
            size[parent1]+=size[parent2];
        }
        else{
            parent[parent1]=parent2;
            size[parent2]+=size[parent1];
        }
    }
    public int numComponents(){
        int ans=0;
        int V=this.parent.length-1;
        for(int i=1;i<=V;i++){
            if(this.parent[i]==i){
                ans++;
            }
        }
        return ans;
    }
    public int componentSize(int vertex){
        int parent=getParent(vertex);
        return size[parent];
    }
}


import java.util.*;
import java.io.*;
public class Main{
    static int faultNodes=0;
    static HashMap<String,Boolean> map;
    public static void main(String args[])throws IOException{
        BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
        String inp[]=br.readLine().trim().split(" ");
        int n=Integer.parseInt(inp[0]);
        int k=Integer.parseInt(inp[1]);
        ArrayList<Integer> arr[]=new ArrayList[n+1];
        for(int i=0;i<=n;i++) arr[i]=new ArrayList<>();
        boolean fault[]=new boolean[n+1];
        int mod=1000000007;
        // for(int i=0;i<n+1;i++) fault[i]=true;
         map=new HashMap<>();
        String key=new String();
        for(int i=0;i<n-1;i++){
            inp=br.readLine().trim().split(" ");
            int a=Integer.parseInt(inp[0]);
            int b=Integer.parseInt(inp[1]);
            int col=Integer.parseInt(inp[2]);
            key=inp[0]+"-"+inp[1];
            map.put(key,col==0);
            key=inp[1]+"-"+inp[0];
            map.put(key,col==0);
            arr[a].add(b);
            arr[b].add(a);
            if(col == 0) fault[a]=fault[b]=true;
        }
        boolean visited[]=new boolean[n+1];
        int totalFaultyNodes=0;
        long toSub=0;
        for(int i=1;i<=n;i++){
            if(!visited[i] && fault[i]){
                faultNodes=0;
                dfs(i,arr,visited,fault);
                totalFaultyNodes+=faultNodes;
                long temp=binexp(faultNodes,k,mod);
                toSub=(toSub%mod + temp%mod)%mod;
            }
        }
        toSub=(toSub%mod + (n-totalFaultyNodes)%mod)%mod;

        long ans=binexp(n,k,mod)%mod-toSub%mod;
        if(ans<0) ans=0;
        System.out.println(ans);
    }

    static void dfs(int i,ArrayList<Integer> arr[],boolean visited[],boolean fault[]){
        visited[i]=true;
        faultNodes++;
        int len=arr[i].size();
        for(int j=0;j<len;j++){
            int index=arr[i].get(j);
            if(!visited[index]){
                String temp=Integer.toString(index)+"-"+Integer.toString(i);
                if(map.get(temp))
                 dfs(index,arr,visited,fault);
            }

        }
    }
    static long binexp(long  a,  long b,  long m) {
    a %= m;
     long res = 1;
    while (b > 0) {
        if (b%2 == 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}
}


import java.util.*;
import java.io.*;
public class Main{
    static int faultNodes=0;
    public static void main(String args[])throws IOException{
        BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
        String inp[]=br.readLine().trim().split(" ");
        int n=Integer.parseInt(inp[0]);
        int k=Integer.parseInt(inp[1]);
        ArrayList<Integer> arr[]=new ArrayList[n+1];
        for(int i=0;i<=n;i++) arr[i]=new ArrayList<>();
        boolean fault[]=new boolean[n+1];
        int mod=1000000007;
        for(int i=0;i<n+1;i++) fault[i]=true;
        for(int i=0;i<n-1;i++){
            inp=br.readLine().trim().split(" ");
            int a=Integer.parseInt(inp[0]);
            int b=Integer.parseInt(inp[1]);
            int col=Integer.parseInt(inp[2]);
            arr[a].add(b);
            arr[b].add(a);
            if(col == 1) fault[a]=fault[b]=false;
        }
        boolean visited[]=new boolean[n+1];
        int totalFaultyNodes=0;
        long toSub=0;
        for(int i=1;i<=n;i++){
            if(!visited[i] && fault[i]){
                faultNodes=0;
                dfs(i,arr,visited,fault);
                totalFaultyNodes+=faultNodes+1;
                long temp=binexp(faultNodes+1,k,mod);
                toSub=(toSub%mod + temp%mod)%mod;
            }
        }
        toSub=(toSub%mod + (n-totalFaultyNodes)%mod)%mod;

        long ans=binexp(n,k,mod)%mod-toSub%mod;
        if(ans<0) ans=0;
        System.out.println(ans);
    }

    static void dfs(int i,ArrayList<Integer> arr[],boolean visited[],boolean fault[]){
        visited[i]=true;
        faultNodes++;
        int len=arr[i].size();
        for(int j=0;j<len;j++){
            int index=arr[i].get(j);
            if(!visited[index] && fault[index])
            dfs(index,arr,visited,fault);
        }
    }
    static long binexp(long  a,  long b,  long m) {
    a %= m;
     long res = 1;
    while (b > 0) {
        if (b%2 == 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}
}


import java.util.*;
import java.io.*;
public class Main{
    static int faultNodes=0;
    static HashMap<String,Boolean> map;
    public static void main(String args[])throws IOException{
        BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
        String inp[]=br.readLine().trim().split(" ");
        int n=Integer.parseInt(inp[0]);
        int k=Integer.parseInt(inp[1]);
        ArrayList<Integer> arr[]=new ArrayList[n+1];
        for(int i=0;i<=n;i++) arr[i]=new ArrayList<>();
        boolean fault[]=new boolean[n+1];
        int mod=1000000007;
        // for(int i=0;i<n+1;i++) fault[i]=true;
         map=new HashMap<>();
        String key=new String();
        for(int i=0;i<n-1;i++){
            inp=br.readLine().trim().split(" ");
            int a=Integer.parseInt(inp[0]);
            int b=Integer.parseInt(inp[1]);
            int col=Integer.parseInt(inp[2]);
            key=inp[0]+"-"+inp[1];
            map.put(key,col==0);
            key=inp[1]+"-"+inp[0];
            map.put(key,col==0);
            arr[a].add(b);
            arr[b].add(a);
            if(col == 0) fault[a]=fault[b]=true;
        }
        boolean visited[]=new boolean[n+1];
        int totalFaultyNodes=0;
        long toSub=0;
        for(int i=1;i<=n;i++){
            if(!visited[i] && fault[i]){
                faultNodes=0;
                dfs(i,arr,visited,fault);
                totalFaultyNodes+=faultNodes;
                long temp=binexp(faultNodes,k,mod);
                toSub=(toSub%mod + temp%mod)%mod;
            }
        }
        toSub=(toSub%mod + (long)(n-totalFaultyNodes)%mod)%mod;

        long ans=(((long)binexp(n,k,mod)%mod-(long)toSub%mod)%mod+mod)%mod;
        // if(ans<0) ans=0;
        // System.out.println(binexp(n,k,mod));
        System.out.println(ans);
    }

    static void dfs(int i,ArrayList<Integer> arr[],boolean visited[],boolean fault[]){
        visited[i]=true;
        faultNodes++;
        int len=arr[i].size();
        for(int j=0;j<len;j++){
            int index=arr[i].get(j);
            if(!visited[index]){
                String temp=Integer.toString(index)+"-"+Integer.toString(i);
                if(map.get(temp))
                 dfs(index,arr,visited,fault);
            }

        }
    }
    static long binexp(long  a,  long b,  long m) {
    a %= m;
     long res = 1;
    while (b > 0) {
        if (b%2 == 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}
}


//package com.fan.Learn.codeforces.p1139;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class C {
    private final int MAX_N = 200000;
    private final int M = 1000000007;

    private int n, k;
    private List<ArrayList<Integer>> G = new ArrayList<>();
    private boolean[] used = new boolean[MAX_N];

    public long mod_pow(long x, long n, long mod) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) == 1) res = res * x % mod;
            x = x * x % mod;
            n >>= 1;
        }
        return res;
    }

    public int dfs(int x) {
        int ans = 1;
        used[x] = true;
        for (int i = 0; i < G.get(x).size(); i++) {
            int v = G.get(x).get(i);
            if (used[v] == false) {
                ans += dfs(v);
            }
        }
        return ans;
    }

    public void solve() {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int k = scan.nextInt();
        for (int i = 0; i < n; i++) {
            ArrayList<Integer> x = new ArrayList<>();
            G.add(x);
        }
        int u, v, t;
        for (int i = 0; i < n - 1; i++) {
            u = scan.nextInt();
            v = scan.nextInt();
            t = scan.nextInt();
            u--;
            v--;
            if (t == 0) {
                G.get(u).add(v);
                G.get(v).add(u);
            }
        }
        long res = mod_pow(n, k, M);
        for (int i = 0; i < n; i++) {
            if (used[i] == false) {
                int x = dfs(i);
                res = (res + M - mod_pow(x, k, M)) % M;
            }
        }
        System.out.println(res);

    }

    public static void main(String[] args) {
        C mn = new C();
        mn.solve();
    }
}


package com.fan.Learn.codeforces.p1139;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class C {
    private final int MAX_N = 20000;
    private final int M = 100000007;

    private int n, k;
    private List<ArrayList<Integer>> G = new ArrayList<>();
    private boolean[] used = new boolean[MAX_N];

    public long mod_pow(long x, long n, long mod) {
        long res = 1;
        while (n > 0) {
            if ((n & 1) == 1) res = res * x % mod;
            x = x * x % mod;
            n >>= 1;
        }
        return res;
    }

    public int dfs(int x) {
        int ans = 1;
        used[x] = true;
        for (int i = 0; i < G.get(x).size(); i++) {
            int v = G.get(x).get(i);
            if (used[v] == false) {
                ans += dfs(v);
            }
        }
        return ans;
    }

    public void solve() {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int k = scan.nextInt();
        for (int i = 0; i < n; i++) {
            ArrayList<Integer> x = new ArrayList<>();
            G.add(x);
        }
        int u, v, t;
        for (int i = 0; i < n - 1; i++) {
            u = scan.nextInt();
            v = scan.nextInt();
            t = scan.nextInt();
            u--;
            v--;
            if (t == 0) {
                G.get(u).add(v);
                G.get(v).add(u);
            }
        }
        long res = mod_pow(n, k, M);
        for (int i = 0; i < n; i++) {
            if (used[i] == false) {
                int x = dfs(i);
                res = (res + M - mod_pow(x, k, M)) % M;
            }
        }
        System.out.println(res);

    }

    public static void main(String[] args) {
        C mn = new C();
        mn.solve();
    }
}


/*
ID: hepic
PROG: ariprog
LANG: C++11
*/
#include<bits/stdc++.h>

#define FOR(i, a, b) for(auto i=a; i!=b+1-2*(a>b); i+=1-2*(a>b))
#define REP(i, a, b) for(auto i=a-(a>b); i!=b-(a>b); i+=1-2*(a>b))
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
#define pf(a) push_front(a)
#define eb(a, b) emplace_back(a, b)
#define fir first
#define sec second
#define what_is(x) cout<<#x<<" is "<<x<<endl;
#define type(x) typeid(x).name()
#define ms(arr, val) memset(arr, val, sizeof(arr))
#define min3(a,b,c) min(min(a,b),c)
#define max3(a,b,c) max(max(a,b),c)
#define SIZE 100010
#define MAXN 1000000007
#define NUM 25
#define PI acos(-1)
#define open_read1 freopen("C:\\Users\\Hepic\\Desktop\\a.txt", "r", stdin)
#define open_write1 freopen("C:\\Users\\Hepic\\Desktop\\b.txt", "w", stdout)
#define open_read freopen("ariprog.in", "r", stdin)
#define open_write freopen("ariprog.out", "w", stdout)

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<double, double> PDD;
typedef pair<int, int> PII;
typedef pair<int, PII> PIPII;
typedef pair<PII, PII> PPIIPII;
typedef pair<LL, LL> PLL;
typedef pair<LL, PLL> PLPLL;

template<typename T, typename T1>
ostream& operator << (ostream &out, pair<T, T1> obj)
{
    return out<<"("<<obj.first<<","<<obj.second<<")";
}

template<typename T, typename T1>
ostream& operator << (ostream &out, map<T, T1> cont)
{
    typename map<T, T1>::const_iterator itr = cont.begin();
    typename map<T, T1>::const_iterator ends = cont.end();

    for(; itr!=ends; ++itr)
        out<<*itr<<" ";
    out<<endl;
}

template<typename T>
ostream& operator << (ostream &out, set<T> cont)
{
    typename set<T>::const_iterator itr = cont.begin();
    typename set<T>::const_iterator ends = cont.end();

    for(; itr!=ends; ++itr)
        out<<*itr<<" ";
    out<<endl;
}

template<typename T>
ostream& operator << (ostream &out, multiset<T> cont)
{
    typename multiset<T>::const_iterator itr = cont.begin();
    typename multiset<T>::const_iterator ends = cont.end();

    for(; itr!=ends; ++itr)
        out<<*itr<<" ";
    out<<endl;
}

template<typename T, template<typename ELEM, typename ALLOC=allocator<ELEM>> class CONT>
ostream& operator << (ostream &out, CONT<T> cont)
{
    typename CONT<T>::const_iterator itr = cont.begin();
    typename CONT<T>::const_iterator ends = cont.end();

    for(; itr!=ends; ++itr)
        out<<*itr<<" ";
    out<<endl;
}

template<typename T, unsigned int N, typename CTy, typename CTr>
typename enable_if<!is_same<T, char>::value, basic_ostream<CTy, CTr> &>::type
operator << (basic_ostream<CTy, CTr> &out, const T (&arr)[N])
{
     REP(i, 0, N)
        out<<arr[i]<<" ";
    out<<endl;
}

template<typename T>
T gcd(T a, T b)
{
    T min_v = min(a, b);
    T max_v = max(a, b);

    while(min_v)
    {
        T temp = max_v % min_v;
        max_v = min_v;
        min_v = temp;
    }

    return max_v;
}

template<typename T>
T lcm(T a, T b)
{
    return (a*b) / gcd(a, b);
}

template<typename T>
T fast_exp_pow(T base, T exp, T mod)
{
    LL res = 1;

    while(exp)
    {
        if(exp&1)
        {
            res *= base;
            res %= mod;
        }

        exp >>= 1;
        base *= base;
        base %= mod;
    }

    return res;
}

/*#################################################################################################################
#################################################################################################################
#################################################################################################################
#################################################################################################################*/

int N, M, S, T, A, B, C, min_dst;
int distanceS[SIZE], distanceT[SIZE];
LL all_ways;
LL waysS[SIZE], waysT[SIZE];
bool visited[SIZE];
vector<PII> graphS[SIZE], graphT[SIZE];
vector<PIPII> roads;
priority_queue<PII, vector<PII>, greater<PII>> que;

void dijkstra(int Tbeg, vector<PII> *graph, int *dists, LL *ways)
{
    ms(visited, false);
    dists[Tbeg] = 0;
    ways[Tbeg] = 1;

    que.push(mp(0, Tbeg));

    while(!que.empty())
    {
        int cost = que.top().fir;
        int node = que.top().sec;
        que.pop();

        visited[node] = true;

        REP(i, 0, graph[node].size())
        {
            int conn_node = graph[node][i].fir;
            int new_cost = graph[node][i].sec;

            if(!visited[conn_node])
            {
                if(!dists[conn_node]  ||  dists[conn_node] > cost+new_cost)
                {
                    que.push(mp(cost+new_cost, conn_node));
                    dists[conn_node] =  cost+new_cost;
                    ways[conn_node] = ways[node];
                }

                else if(dists[conn_node] == cost+new_cost)
                    ways[conn_node] = (ways[conn_node] + ways[node]) % MAXN;
            }
        }
    }
}

int main()
{
    //open_read1;
    scanf("%d%d%d%d", &N, &M, &S, &T);

    REP(i, 0, M)
    {
        scanf("%d%d%d", &A, &B, &C);

        graphS[A].eb(B, C);
        graphT[B].eb(A, C);
        roads.eb(C, mp(A, B));
    }

    dijkstra(S, graphS, distanceS, waysS);
    dijkstra(T, graphT, distanceT, waysT);
    min_dst = distanceS[T];
    all_ways = waysS[T];

    REP(i, 0, M)
    {
        int node1 = roads[i].sec.fir;
        int node2 = roads[i].sec.sec;
        int dst = distanceS[node1] + roads[i].fir + distanceT[node2];
        LL ways = (waysS[node1] * waysT[node2]) % MAXN;

        if(!ways)
        {
            printf("NO\n");
            continue;
        }

        if(dst == min_dst)
        {
            if(ways == all_ways)
                printf("YES\n");

            else
            {
                if(roads[i].fir > 1)
                    printf("CAN 1\n");
                else
                    printf("NO\n");
            }
        }

        else if(dst > min_dst)
        {
            int val = dst - min_dst + 1;

            if(roads[i].fir - val >= 1)
                printf("CAN %d\n", val);
            else
                printf("NO\n");
        }
    }

    return 0;
}


/*
ID: hepic
PROG: lamps
LANG: C++11
*/
#include<bits/stdc++.h>

#define FOR(i, a, b) for(auto i=a; i!=b+1-2*(a>b); i+=1-2*(a>b))
#define REP(i, a, b) for(auto i=a-(a>b); i!=b-(a>b); i+=1-2*(a>b))
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define pb(a) push_back(a)
#define pf(a) push_front(a)
#define eb(a, b) emplace_back(a, b)
#define fir first
#define sec second
#define what_is(x) cout<<#x<<" is "<<x<<endl;
#define min3(a,b,c) min(min(a,b),c)
#define max3(a,b,c) max(max(a,b),c)
#define SIZE 100010
#define MAXN 1e8 + 7
#define NUM 200010
#define PI acos(-1)
#define open_read1 freopen("C:\\Users\\Hepic\\Desktop\\a.txt","r",stdin)
#define open_write1 freopen("C:\\Users\\Hepic\\Desktop\\b.txt","w",stdout)
#define open_read freopen("cruise.in","r",stdin)
#define open_write freopen("cruise.out","w",stdout)

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<int, PII> PIPII;
typedef pair<PII, PII> PPIIPII;
typedef pair<LL, LL> PLL;
typedef pair<LL, PLL> PLPLL;

template<typename T, typename T1>
ostream& operator << (ostream &out, pair<T, T1> obj)
{
    return out<<"("<<obj.first<<","<<obj.second<<")";
}

template<typename T, typename T1>
ostream& operator << (ostream &out, map<T, T1> cont)
{
    typename map<T, T1>::const_iterator itr = cont.begin();
    typename map<T, T1>::const_iterator ends = cont.end();

    for(; itr!=ends; ++itr)
        out<<*itr<<" ";
    out<<endl;
}

template<typename T>
ostream& operator << (ostream &out, set<T> cont)
{
    typename set<T>::const_iterator itr = cont.begin();
    typename set<T>::const_iterator ends = cont.end();

    for(; itr!=ends; ++itr)
        out<<*itr<<" ";
    out<<endl;
}

template<typename T, template<typename ELEM, typename ALLOC=allocator<ELEM>> class CONT>
ostream& operator << (ostream &out, CONT<T> cont)
{
    typename CONT<T>::const_iterator itr = cont.begin();
    typename CONT<T>::const_iterator ends = cont.end();

    for(; itr!=ends; ++itr)
        out<<*itr<<" ";
    out<<endl;
}

template<typename T>
T gcd(T a, T b)
{
    T min_v = min(a, b);
    T max_v = max(a, b);

    while(min_v)
    {
        T temp = max_v % min_v;
        max_v = min_v;
        min_v = temp;
    }

    return max_v;
}

template<typename T>
T lcm(T a, T b)
{
    return (a*b) / gcd(a, b);
}

/*#################################################################################################################
#################################################################################################################
#################################################################################################################
#################################################################################################################*/

LL N, M, CAPITAL, HOME, A, B, C;
LL home_dst[SIZE], capital_dst[SIZE];
LL home_cnt[SIZE], capital_cnt[SIZE];
bool visited[SIZE];
vector<PLL> capital_graph[SIZE], home_graph[SIZE];
vector<PLPLL> roads;
priority_queue<PLL, vector<PLL>, greater<PLL>> que;

void initialize()
{
    while(!que.empty())
        que.pop();

    REP(i, 0, SIZE)
        visited[i] = false;
}

void dijkstra(vector<PLL> *graph, LL nde, LL *Tdistances, LL *Tcounts)
{
    initialize();
    que.push(mp(0, nde));
    Tdistances[nde] = 0;
    Tcounts[nde] = 1;

    while(!que.empty())
    {
        LL node = que.top().sec;
        LL dst = que.top().fir;
        que.pop();

        visited[node] = true;

        REP(i, 0, graph[node].size())
        {
            LL conn_node = graph[node][i].fir;
            LL conn_dst = graph[node][i].sec;

            if(!visited[conn_node])
            {
                if(!Tdistances[conn_node]  ||  Tdistances[conn_node] > dst+conn_dst)
                {
                    que.push(mp(dst+conn_dst, conn_node));
                    Tdistances[conn_node] = dst+conn_dst;
                    Tcounts[conn_node] = Tcounts[node];
                }

                else if(Tdistances[conn_node] == dst+conn_dst)
                    Tcounts[conn_node] = (Tcounts[conn_node] + Tcounts[node]) % MAXN;
            }
        }
    }
}

int main()
{
    //open_read1;
    scanf("%I64d%I64d%I64d%I64d", &N, &M, &CAPITAL, &HOME);

    REP(i, 0, M)
    {
        scanf("%I64d%I64d%I64d", &A, &B, &C);

        capital_graph[A].pb(mp(B, C));
        home_graph[B].pb(mp(A, C));

        roads.pb(mp(C, mp(A, B)));
    }

    dijkstra(capital_graph, CAPITAL, capital_dst, capital_cnt);
    dijkstra(home_graph, HOME, home_dst, home_cnt);

    REP(i, 0, M)
    {
        LL len = roads[i].fir;
        LL cityA = roads[i].sec.fir;
        LL cityB = roads[i].sec.sec;

        LL dist = capital_dst[cityA] + len + home_dst[cityB];
        LL cnt_ways = (capital_cnt[cityA] * home_cnt[cityB]) % MAXN;

        if(!cnt_ways)
        {
            printf("NO\n");
            continue;
        }

        if(dist == capital_dst[HOME])
        {
            if(cnt_ways == capital_cnt[HOME])
                printf("YES\n");

            else if(cnt_ways < capital_cnt[HOME])
            {
                if(len > 1)
                    printf("CAN 1\n");

                else if(len <= 1)
                    printf("NO\n");
            }
        }

        else if(dist > capital_dst[HOME])
        {
            LL diff = dist - capital_dst[HOME] + 1;

            if(len-diff >= 1)
                printf("CAN %I64d\n", diff);

            else
                printf("NO\n");
        }
    }

    return 0;
}