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 CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
long long n, m, g1, g2, s1, s2;
const long long max_n = 52;
vector<pair<long long, long long>> ad_list[max_n];
long long d[max_n][max_n][max_n];
long long save[max_n];
bool mark[max_n];
vector<long long> dis[max_n];
set<pair<long long, long long>> st;
void update(long long v) {
  mark[v] = 1;
  for (long long i = 0; i < ad_list[v].size(); i++) {
    long long u = ad_list[v][i].first;
    long long w = ad_list[v][i].second;
    if (mark[u]) continue;
    if (save[u] == -1 || save[u] > save[v] + w) {
      if (save[u] != -1) st.erase({save[u], u});
      save[u] = save[v] + w;
      st.insert({save[u], u});
    }
  }
}
long long find_min() {
  pair<long long, long long> temp = *st.begin();
  st.erase(temp);
  return temp.second;
}
void dijk(long long root) {
  fill(mark, mark + n, 0);
  fill(save, save + n, -1);
  save[root] = 0;
  update(root);
  long long mini;
  while (!st.empty()) {
    mini = find_min();
    update(mini);
  }
  for (long long i = 0; i < n; i++) {
    if (i == root) continue;
    dis[root].push_back(save[i]);
  }
  sort(dis[root].begin(), dis[root].end());
  dis[root].resize(unique(dis[root].begin(), dis[root].end()) -
                   dis[root].begin());
}
bool lesss(long long min_g, long long ind, long long x) {
  if (dis[min_g][0] > x) return true;
  if (dis[min_g][0] < x) return false;
  if (min_g < ind) return false;
  return true;
}
bool more(long long max_b, long long ind, long long x) {
  if (dis[max_b][dis[max_b].size() - 1] < x) return true;
  if (dis[max_b][dis[max_b].size() - 1] > x) return false;
  if (max_b > ind) return false;
  return true;
}
long long get(long long min_g, long long max_b) {
  if (lesss(min_g, max_b, dis[max_b][dis[max_b].size() - 1])) return 0;
  for (long long i = 0; i <= n; i++)
    for (long long j = 0; j <= n; j++)
      for (long long w = 0; w <= n; w++) d[i][j][w] = 0;
  for (long long i = 0; i < n; i++) {
    bool fg, fs, fb;
    fg = fs = fb = 0;
    for (long long j = 0; j < dis[i].size(); j++) {
      if (i == min_g) {
        fg = 1;
        continue;
      }
      if (i == max_b) {
        fb = 1;
        continue;
      }
      if (lesss(min_g, i, dis[i][j])) fg = 1;
      if (more(max_b, i, dis[i][j])) fb = 1;
      if (dis[min_g][0] > dis[i][j]) continue;
      if (dis[min_g][0] == dis[i][j] && min_g >= i) continue;
      if (dis[max_b][dis[max_b].size() - 1] < dis[i][j]) continue;
      if (dis[max_b][dis[max_b].size() - 1] == dis[i][j] && max_b <= i)
        continue;
      fs = 1;
    }
    if (i == 0) {
      if (fg) d[i][0][1] = 1;
      if (fb) d[i][0][0] = 1;
      if (fs) d[i][1][0] = 1;
      continue;
    }
    for (long long s = 0; s <= n; s++)
      for (long long g = 0; g <= n; g++) {
        if (fb) d[i][s][g] += d[i - 1][s][g];
        if (fs && s > 0) d[i][s][g] += d[i - 1][s - 1][g];
        if (fg && g > 0) d[i][s][g] += d[i - 1][s][g - 1];
      }
  }
  long long ret = 0;
  for (long long i = g1; i <= g2; i++)
    for (long long j = s1; j <= s2; j++) ret += d[n - 1][j][i];
  return ret;
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(0);
  {
    cin >> n >> m;
    long long a, b, c;
    for (long long i = 0; i < m; i++) {
      cin >> a >> b >> c;
      a--;
      b--;
      ad_list[a].push_back({b, c});
      ad_list[b].push_back({a, c});
    }
  }
  {
    for (long long i = 0; i < n; i++) dijk(i);
    cin >> g1 >> g2;
    cin >> s1 >> s2;
  }
  long long ans = 0;
  for (long long i = 0; i < n; i++)
    for (long long j = 0; j < n; j++) {
      if (i == j) continue;
      long long t = get(i, j);
      ans += t;
    }
  cout << ans << endl;
  return 0;
}