#include <bits/stdc++.h>
using namespace std;
const long long INF = 1001001001001001001;
vector<int> used(105, 0);
struct edge {
  long long to, cost, id;
};
vector<long long> Djikstra(long long n, vector<vector<edge>> &G,
                           long long start) {
  priority_queue<pair<long long, long long>, vector<pair<long long, long long>>,
                 greater<pair<long long, long long>>>
      que;
  vector<long long> min_dist(n + 1);
  fill(min_dist.begin(), min_dist.end(), INF);
  min_dist[start] = 0;
  que.push(make_pair(0, start));
  while (!que.empty()) {
    pair<long long, long long> top = que.top();
    que.pop();
    long long v = top.second;
    if (min_dist[v] < top.first) continue;
    for (long long i = 0; i < G[v].size(); ++i) {
      edge e = G[v][i];
      if (min_dist[e.to] > min_dist[v] + e.cost) {
        used[e.id] = 1;
        min_dist[e.to] = min_dist[v] + e.cost;
        que.push(make_pair(min_dist[e.to], e.to));
      }
    }
  }
  return min_dist;
}
int main() {
  long long n, m;
  cin >> n >> m;
  vector<vector<edge>> s2g(n), g2s(n);
  for (long long i = 0; i < m; ++i) {
    long long a, b, c;
    cin >> a >> b >> c;
    a--, b--;
    edge e_from_s, e_from_g;
    e_from_s.to = b, e_from_g.to = a;
    e_from_s.cost = e_from_g.cost = c;
    e_from_s.id = e_from_g.id = i;
    s2g[a].push_back(e_from_s);
    g2s[b].push_back(e_from_g);
  }
  vector<long long> dist_s2g = Djikstra(n, s2g, 0);
  long long ans = 0;
  for (long long i = 0; i < m; ++i) {
    if (used[i] == 0) ans++;
  }
  cout << ans;
}
