Problem: On the Berland Dependence Day it was decided to organize a great marathon. Berland consists of n cities, some of which are linked by two-way roads. Each road has a certain length. The cities are numbered from 1 to n. It is known that one can get from any city to any other one by the roads.

n runners take part in the competition, one from each city. But Berland runners are talkative by nature and that's why the juries took measures to avoid large crowds of marathon participants. The jury decided that every runner should start the marathon from their hometown. Before the start every sportsman will get a piece of paper containing the name of the city where the sportsman's finishing line is. The finish is chosen randomly for every sportsman but it can't coincide with the sportsman's starting point. Several sportsmen are allowed to finish in one and the same city. All the sportsmen start simultaneously and everyone runs the shortest route from the starting point to the finishing one. All the sportsmen run at one speed which equals to 1.

After the competition a follow-up table of the results will be composed where the sportsmen will be sorted according to the nondecrease of time they spent to cover the distance. The first g sportsmen in the table will get golden medals, the next s sportsmen will get silver medals and the rest will get bronze medals. Besides, if two or more sportsmen spend the same amount of time to cover the distance, they are sorted according to the number of the city where a sportsman started to run in the ascending order. That means no two sportsmen share one and the same place.

According to the rules of the competition the number of gold medals g must satisfy the inequation g1 ≤ g ≤ g2, where g1 and g2 are values formed historically. In a similar way, the number of silver medals s must satisfy the inequation s1 ≤ s ≤ s2, where s1 and s2 are also values formed historically.

At present, before the start of the competition, the destination points of every sportsman are unknown. However, the press demands details and that's why you are given the task of counting the number of the ways to distribute the medals. Two ways to distribute the medals are considered different if at least one sportsman could have received during those distributions different kinds of medals.

Input

The first input line contains given integers n and m (3 ≤ n ≤ 50, n - 1 ≤ m ≤ 1000), where n is the number of Berland towns and m is the number of roads.

Next in m lines road descriptions are given as groups of three integers v, u, c, which are the numbers of linked towns and its length (1 ≤ v, u ≤ n, v ≠ u, 1 ≤ c ≤ 1000). Every pair of cities have no more than one road between them.

The last line contains integers g1, g2, s1, s2 (1 ≤ g1 ≤ g2, 1 ≤ s1 ≤ s2, g2 + s2 < n). The input data numbers, located on one line, are space-separated.

Output

Print the single number — the number of ways to distribute the medals. It is guaranteed that the number fits in the standard 64-bit signed data type.

Examples

Input

3 2
1 2 1
2 3 1
1 1 1 1


Output

3


Input

4 5
1 2 2
2 3 1
3 4 2
4 1 2
1 3 3
1 2 1 1


Output

19


Input

3 3
1 2 2
2 3 1
3 1 2
1 1 1 1


Output

4

Solution (in JAVA):

Solution:
import java.io.*;

import java.awt.geom.Point2D;
import java.text.*;
import java.math.*;
import java.util.*;

public class Main implements Runnable {

	final String filename = "";

	public void solve() throws Exception {
		final int INF = 60000;
		int n = iread(), m = iread();
		int[][] ss = new int[n][n];
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				ss[i][j] = INF;
		for (int i = 0; i < n; i++)
			ss[i][i] = 0;
		for (int i = 0; i < m; i++) {
			int a = iread(), b = iread(), c = iread();
			a--;
			b--;
			ss[a][b] = c;
			ss[b][a] = c;
		}
		int g1 = iread(), g2 = iread(), s1 = iread(), s2 = iread();
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				for (int k = 0; k < n; k++)
					ss[j][k] = Math.min(ss[j][k], ss[j][i] + ss[i][k]);
		int[] worst = new int[n + 1];
		int[] best = new int[n + 1];
		Arrays.fill(worst, INF);
		Arrays.fill(best, -1);
		worst[n] = 0;
		best[n] = INF;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (j == i)
					continue;
				best[i] = Math.max(best[i], ss[i][j]);
				worst[i] = Math.min(worst[i], ss[i][j]);
			}
		}

		long[][] C = new long[51][51];
		C[0][0] = 1;
		for (int i = 1; i <= 50; i++) {
			C[i][0] = 1;
			C[i][i] = 1;
			for (int j = 1; j < i; j++)
				C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
		}

		long ans = 0;
		for (int a = 0; a <= n; a++)
			// �������� ������
			cycle: for (int b = 0; b < n; b++) // ��������� ������
			{
				if (a == b)
					continue;
				int[] d = new int[8];
				for (int i = 0; i < n; i++) {
					if (i == a) {
						d[1]++;
						continue;
					}
					if (i == b) {
						d[4]++;
						continue;
					}
					int mask = 0;
					for (int j = 0; j < n; j++) {
						if (i == j)
							continue;
						if (ss[i][j] > best[a] || ss[i][j] == best[a] && i > a)
							mask |= 1;
						else if (ss[i][j] > worst[b] || ss[i][j] == worst[b]
								&& i > b)
							mask |= 2;
						else
							mask |= 4;
					}
					d[mask]++;
				}
				long[][][] t = new long[5][n + 1][n + 1];
				int min_g = d[4], min_s = d[2];
				t[0][min_g][min_s] = 1;

				int s = 0;
				for (int u = min_g; u <= n; u++)
					for (int v = min_s; v <= n; v++) {
						if (t[s][u][v] == 0)
							continue;
						for (int i = 0; i <= d[3]; i++)
							t[s + 1][u][v + i] += t[s][u][v] * C[d[3]][i];
					}
				s = 1;
				for (int u = min_g; u <= n; u++)
					for (int v = min_s; v <= n; v++) {
						if (t[s][u][v] == 0)
							continue;
						for (int i = 0; i <= d[5]; i++)
							t[s + 1][u + i][v] += t[s][u][v] * C[d[5]][i];
					}
				s = 2;
				for (int u = min_g; u <= n; u++)
					for (int v = min_s; v <= n; v++) {
						if (t[s][u][v] == 0)
							continue;
						for (int i = 0; i <= d[6]; i++)
							t[s + 1][u + i][v + d[6] - i] += t[s][u][v]
									* C[d[6]][i];
					}
				s = 3;
				for (int u = min_g; u <= n; u++)
					for (int v = min_s; v <= n; v++) {
						if (t[s][u][v] == 0)
							continue;
						for (int i = 0; i <= d[7]; i++)
							for (int j = 0; i + j <= d[7]; j++)
								t[s + 1][u + i][v + j] += t[s][u][v]
										* C[d[7]][i] * C[d[7] - i][j];
					}
				for (int g = g1; g <= g2; g++)
					for (s = s1; s <= s2; s++)
						ans += t[4][g][s];
			}
		out.write(ans + "\n");
	}

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new BufferedWriter(new OutputStreamWriter(System.out));
			// in = new BufferedReader(new FileReader(filename+".in"));
			// out = new BufferedWriter(new FileWriter(filename+".out"));
			solve();
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	public int iread() throws Exception {
		return Integer.parseInt(readword());
	}

	public double dread() throws Exception {
		return Double.parseDouble(readword());
	}

	public long lread() throws Exception {
		return Long.parseLong(readword());
	}

	BufferedReader in;

	BufferedWriter out;

	public String readword() throws IOException {
		StringBuilder b = new StringBuilder();
		int c;
		c = in.read();
		while (c >= 0 && c <= ' ')
			c = in.read();
		if (c < 0)
			return "";
		while (c > ' ') {
			b.append((char) c);
			c = in.read();
		}
		return b.toString();
	}

	public static void main(String[] args) {
		try {
			Locale.setDefault(Locale.US);
		} catch (Exception e) {

		}
		new Thread(new Main()).start();
		// new Thread(null, new Main(), "1", 1<<25).start();
	}
}