#include <bits/stdc++.h>
using namespace std;
typedef struct Edge {
  unsigned from;
  unsigned to;
} Edge;
int main() {
  int N, M;
  cin >> N >> M;
  unsigned C[101][101];
  for (int ii = 1; ii <= N; ++ii)
    for (int jj = 1; jj <= N; ++jj)
      if (ii != jj)
        C[ii][jj] = UINT32_MAX;
      else
        C[ii][jj] = 0;
  for (int m = 0; m < M; ++m) {
    unsigned a, b, c;
    cin >> a >> b >> c;
    C[a][b] = c;
    C[b][a] = c;
  }
  unsigned DIST[101][101];
  for (int ii = 1; ii <= N; ++ii)
    for (int jj = 1; jj <= N; ++jj) DIST[ii][jj] = UINT32_MAX;
  bool GOOD[101][101];
  for (int ii = 1; ii <= N; ++ii)
    for (int jj = 1; jj <= N; ++jj) GOOD[ii][jj] = false;
  for (int start = 1; start <= N; ++start) {
    multimap<unsigned, Edge> Q;
    Edge ee;
    ee.from = start;
    ee.to = start;
    Q.emplace(0, ee);
    while (!Q.empty()) {
      unsigned cost = Q.begin()->first;
      unsigned point_to = Q.begin()->second.to;
      unsigned point_from = Q.begin()->second.from;
      Q.erase(Q.begin());
      if (DIST[start][point_to] > cost) {
        DIST[start][point_to] = cost;
        GOOD[point_from][point_to] = true;
        GOOD[point_to][point_from] = true;
      }
      for (int next = 1; next <= N; ++next) {
        unsigned cost_next = cost + C[point_to][next];
        if (DIST[start][next] > cost_next) {
          Edge e;
          e.from = point_to;
          e.to = next;
          Q.emplace(cost_next, e);
        }
      }
    }
  }
  unsigned count = 0;
  for (unsigned from = 1; from <= N; ++from) {
    for (unsigned to = 1; to < from; ++to) {
      if (C[from][to] < UINT32_MAX && !GOOD[from][to]) {
        ++count;
      }
    }
  }
  cout << count << endl;
  return 0;
}
