#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using P = pair<int, int>;
struct edge {
  int to, we;
  bool operator<(const edge& o) const { return we < o.we; }
};
struct edge_ {
  int fr, to, we;
  bool operator<(const edge_& o) const { return we < o.we; }
};
class UnionFind {
 public:
  vector<int> par;
  UnionFind(int N) : par(N, -1) {}
  bool unite(int x, int y) {
    x = root(x), y = root(y);
    if (x == y) return false;
    if (par[x] > par[y]) swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  bool find(int x, int y) { return root(x) == root(y); }
  int root(int x) { return par[x] < 0 ? x : par[x] = root(par[x]); }
};
int main() {
  int n, m;
  cin >> n >> m;
  UnionFind uf(n);
  vector<vector<edge>> v(n);
  vector<edge_> w;
  vector<vector<int>> d(n, vector<int>(n, 1 << 30));
  {
    priority_queue<edge_> que;
    for (ll i = 0; i < (ll)m; i++) {
      int a, b, c;
      cin >> a >> b >> c;
      a--, b--;
      que.push({a, b, c});
    }
    while (!que.empty()) {
      edge_ nv = que.top();
      que.pop();
      if (!uf.unite(nv.fr, nv.to)) {
        w.push_back({nv});
        continue;
      }
      v[nv.fr].push_back({nv.to, nv.we});
      v[nv.to].push_back({nv.fr, nv.we});
      d[nv.fr][nv.to] = d[nv.to][nv.fr] = nv.we;
    }
  }
  for (ll i = 0; i < (ll)n; i++) d[i][i] = 0;
  for (ll K = 0; K < (ll)n; K++)
    for (ll i = 0; i < (ll)n; i++)
      for (ll j = 0; j < (ll)n; j++) d[i][j] = min(d[i][j], d[i][K] + d[K][j]);
  ll res = n - 1;
  for (ll i = 0; i < (ll)w.size(); i++) {
    vector<vector<edge>> k = v;
    k[w[i].fr].push_back({w[i].to, w[i].we});
    k[w[i].to].push_back({w[i].fr, w[i].we});
    priority_queue<edge> que;
    que.push({0, w[i].fr});
    vector<int> dist(n, 1 << 30);
    dist[w[i].fr] = 0;
    while (!que.empty()) {
      edge ov = que.top();
      que.pop();
      if (ov.we > dist[ov.to]) continue;
      for (auto nv : v[ov.to]) {
        if (dist[nv.to] <= nv.we + dist[ov.to]) continue;
        dist[nv.to] = nv.we + dist[ov.to];
        que.push({dist[nv.to], nv.to});
      }
    }
    if (dist[w[i].to] <= d[w[i].fr][w[i].to]) res++;
  }
  cout << m - res << endl;
  return 0;
}
