#include <bits/stdc++.h>
using namespace std;
class edge {
 public:
  int to, w;
  bool used;
  edge(int to, int w) : to(to), w(w), used(false){};
  void print() { cout << " to: " << to << " w: " << w << endl; }
};
class node {
 public:
  int num;
  vector<edge> edges;
  node(int num) : num(num) {}
  node() { num = -1; }
  void print() {
    cout << "num: " << num << endl;
    for (int i = 0; i < edges.size(); i++) {
      edges[i].print();
    }
  }
};
class graph {
 public:
  int num;
  static int nums;
  vector<node> nodes;
  graph(int num) : num(num) {
    for (int i = 1; i <= num; i++) {
      nodes.push_back(node(++nums));
    }
  }
  void print() {
    for (int i = 1; i <= num; i++) {
      nodes[i].print();
    }
  }
  int solve() {
    for (int i = 1; i <= num; i++) {
      dijkstra(i);
    }
    int ans = 0;
    for (int i = 1; i <= num; i++) {
      node now = nodes[i];
      for (int j = 0; j < now.edges.size(); j++) {
        if (!now.edges[j].used) ans++;
      }
    }
    return ans;
  }
  void dijkstra(int s) {
    const int inf = 1e7;
    int prev[num + 1];
    int dis[num + 1];
    for (int i = 1; i <= num; i++) {
      prev[i] = -1;
      dis[i] = inf;
    }
    priority_queue<pair<int, int>, vector<pair<int, int> >,
                   greater<pair<int, int> > >
        pq;
    pq.push(pair<int, int>(0, s));
    dis[s] = 0, prev[s] = s;
    while (!pq.empty()) {
      pair<int, int> now = pq.top();
      pq.pop();
      int n = now.second, d = now.first;
      if (dis[n] < d) continue;
      for (int i = 0; i < nodes[n].edges.size(); i++) {
        int newd = dis[n] + nodes[n].edges[i].w, next = nodes[n].edges[i].to;
        if (newd < dis[next]) {
          pq.push(pair<int, int>(newd, next));
          dis[next] = newd;
          prev[next] = n;
        }
      }
    }
    for (int i = 1; i <= num; i++) {
      int to = i, from = prev[i];
      while (to != from) {
        for (int j = 0; j < nodes[from].edges.size(); j++) {
          if (nodes[from].edges[j].to == to) {
            nodes[from].edges[j].used = true;
          }
        }
        for (int j = 0; j < nodes[to].edges.size(); j++) {
          if (nodes[to].edges[j].to == from) {
            nodes[from].edges[j].used = true;
          }
        }
        to = from;
        from = prev[from];
      }
    }
  }
};
int graph::nums = 0;
int main() {
  int n, m;
  cin >> n >> m;
  graph g(n);
  for (int i = 0; i < m; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    g.nodes[a].num = a;
    g.nodes[a].edges.push_back(edge(b, c));
    g.nodes[b].num = b;
    g.nodes[b].edges.push_back(edge(a, c));
  }
  cout << g.solve() << endl;
  return 0;
}
