#include <bits/stdc++.h>
using namespace std;
const int infint = INT_MAX;
const long long infll = LLONG_MAX;
int n;
const int MAX = 1e5 + 10;
vector<pair<int, int> > adj[MAX];
long long below[MAX], fBelow[MAX], fAbove[MAX];
long long ans = 0;
bool isLuck(int nr) {
  while (nr > 0) {
    if (nr % 10 != 7 && nr % 10 != 4) return false;
    nr /= 10;
  }
  return true;
}
int dfs(int v, int par) {
  int res = 0;
  for (auto i : adj[v]) {
    if (i.first == par) continue;
    res += dfs(i.first, v);
  }
  return below[v] = res + 1;
}
long long computeBelow(int v, int par) {
  long long sum = 0;
  for (auto i : adj[v]) {
    if (i.first == par) continue;
    if (i.second) {
      sum += below[i.first];
      computeBelow(i.first, v);
    } else
      sum += computeBelow(i.first, v);
  }
  return fBelow[v] = sum;
}
set<pair<int, int> > gEdges;
void computeAbove(int v, int par) {
  if (par != -1) {
    if (gEdges.find({v, par}) != gEdges.end()) {
      fAbove[v] = below[1] - below[v];
    } else
      fAbove[v] = fBelow[par] - fBelow[v] + fAbove[par];
  }
  for (auto i : adj[v]) {
    if (i.first == par) continue;
    computeAbove(i.first, v);
  }
}
int main() {
  memset(below, 0, sizeof(below));
  memset(fBelow, 0, sizeof(fBelow));
  memset(fAbove, 0, sizeof(fAbove));
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v, nr;
    cin >> u >> v >> nr;
    bool luck = isLuck(nr);
    adj[u].push_back({v, luck});
    adj[v].push_back({u, luck});
    if (luck) {
      gEdges.insert({u, v});
      gEdges.insert({v, u});
    }
  }
  dfs(1, -1);
  computeBelow(1, -1);
  computeAbove(1, -1);
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    ans += (fBelow[i] * (fBelow[i] - 1LL)) + (fAbove[i] * (fAbove[i] - 1)) +
           (2LL * (fBelow[i] * fAbove[i]));
  }
  cout << ans;
  return 0;
}
