#include <bits/stdc++.h>
using namespace std;
template <typename T>
using vector2d = vector<vector<T>>;
using Edge = tuple<int, int, int>;
const int INF = 1e8;
namespace UnionFind {
template <typename T>
void init(vector<T> &u) {
  for (int i = 0; i < u.size(); i++) {
    u[i].parent = i;
    u[i].group.insert(i);
  }
}
template <typename T>
int root(vector<T> &u, int x) {
  if (x < 0 || u.size() <= x) {
    return -1;
  } else if (u[x].parent == x) {
    return x;
  } else {
    return u[x].parent = root(u, u[x].parent);
  }
}
template <typename T>
bool connect(vector<T> &u, int a, int b) {
  a = root(u, a), b = root(u, b);
  if (a == b || a < 0 || b < 0) return false;
  {
    u[a].group.insert(u[b].group.begin(), u[b].group.end());
    u[b].group.clear();
  }
  u[b].parent = a;
  return true;
}
template <typename T>
void count(vector<T> &u, map<int, int> &ret) {
  for (int i = 0; i < u.size(); i++) {
    int tmp = u[i].parent;
    if (!ret.count(tmp)) {
      ret[tmp] = 0;
    }
    ret[tmp]++;
  }
}
};  // namespace UnionFind
using namespace UnionFind;
struct Node {
  int parent;
  set<int> group;
};
int main() {
  int N, M;
  cin >> N >> M;
  int ans = 0;
  vector<Edge> edge;
  vector<Node> tree(N);
  init(tree);
  vector2d<int> D(N, vector<int>(N, INF));
  for (int i = 0; i < M; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    a--, b--;
    if (a == b) {
      ans++;
      continue;
    }
    edge.emplace_back(c, a, b);
  }
  sort(edge.begin(), edge.end());
  for (int i = 0; i < edge.size(); i++) {
    int c, a, b;
    tie(c, a, b) = edge[i];
    if (root(tree, a) != root(tree, b)) {
      connect(tree, a, b);
      set<int> &s = tree[root(tree, a)].group;
      set<int> &t = tree[root(tree, b)].group;
      for (auto j = s.begin(); j != s.end(); j++) {
        for (auto k = t.begin(); k != t.end(); k++) {
          if (D[*j][*k] >= D[*j][a] + c + D[b][*k]) {
            D[*j][*k] = D[*j][a] + c + D[b][*k];
          }
        }
      }
    } else {
      set<int> &s = tree[root(tree, a)].group;
      bool place_flag = false;
      for (auto j = s.begin(); j != s.end(); j++) {
        for (auto k = s.begin(); k != s.end(); k++) {
          if (D[*j][*k] >= D[*j][a] + c + D[b][*k]) {
            D[*j][*k] = D[*j][a] + c + D[b][*k];
            place_flag = true;
          }
        }
      }
      if (!place_flag) ans++;
    }
  }
  cout << ans << endl;
  return 0;
}
