#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using vpii = vector<pii>;
using vi = vector<int>;
using vvi = vector<vi>;
using vs = vector<string>;
using data = tuple<int, int, int>;
struct edge {
  int to, cost, id;
};
vector<edge> G[105];
bool used[105];
int d[105];
void dijkstra(int s) {
  fill_n(d, 105, 1e9);
  priority_queue<data, vector<data>, greater<data>> q;
  d[s] = 0;
  q.push(data(0, s, 101));
  while (q.size()) {
    data dat = q.top();
    q.pop();
    int sum, v, eid;
    tie(sum, v, eid) = dat;
    if (d[v] < sum) continue;
    used[eid] = true;
    for (edge e : G[v]) {
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        q.push(data(d[e.to], e.to, e.id));
      }
    }
  }
}
signed main() {
  int N, M;
  cin >> N >> M;
  for (int i = 0; i < M; ++i) {
    int a, b, c;
    cin >> a >> b >> c;
    --a, --b;
    G[a].push_back(edge{b, c, i});
    G[b].push_back(edge{a, c, i});
  }
  for (int i = 0; i < N; ++i) dijkstra(i);
  int ans = 0;
  for (int i = 0; i < M; ++i) {
    if (!used[i]) ans++;
  }
  cout << ans << endl;
}
