#include <bits/stdc++.h>
using namespace std;
const long long N = 1e3 + 10;
const long long INF = 1e18;
struct edge {
  long long to, cost;
};
vector<edge> G[N];
bool judge[N][N];
void dikstra(long long s, long long n) {
  priority_queue<pair<long long, long long>, vector<pair<long long, long long>>,
                 greater<pair<long long, long long>>>
      que;
  long long d[N];
  fill(d, d + N, INF);
  d[s] = 0;
  que.push({0, s});
  long long path[N];
  fill(path, path + N, 0);
  while (!que.empty()) {
    pair<long long, long long> p = que.top();
    que.pop();
    long long v = p.second;
    if (d[v] < p.first) continue;
    for (long long i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        path[e.to] = v;
        que.push({d[e.to], e.to});
      }
    }
  }
  for (long long i = 1; i <= n; i++) {
    if (s == i) continue;
    long long j = i;
    while (1) {
      if (path[j] == 0) break;
      judge[path[j]][j] = 0;
      if (path[j] == s) break;
      j = path[j];
    }
  }
}
signed main() {
  long long n, m;
  cin >> n >> m;
  for (long long i = 0; i < m; i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    G[a].push_back({b, c});
    judge[a][b]++;
  }
  dikstra(1, n);
  long long ans = 0;
  for (long long i = 1; i < N; i++) {
    for (long long j = 1; j < N; j++) {
      if (judge[i][j]) ans++;
    }
  }
  cout << ans << endl;
  return 0;
}
