#include <bits/stdc++.h>
using namespace std;
const int MX = 100005, INF = 1001001001;
const long long int LINF = 1e18;
const double eps = 1e-10;
const int DIV = 1e9 + 7;
int cost[101][101];
int d[101];
bool used[101];
int n, m;
bool usedp[101][101];
int prv[101];
void dijkstra(int s) {
  fill(d, d + n, INF);
  fill(used, used + n, false);
  fill(prv, prv + n, -1);
  d[s] = 0;
  while (true) {
    int v = -1;
    for (int u = 0; u < (n); ++u)
      if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
    if (v == -1) break;
    used[v] = true;
    for (int u = 0; u < (n); ++u) {
      if (d[u] > d[v] + cost[v][u]) {
        d[u] = d[v] + cost[v][u];
        prv[u] = v;
      }
    }
  }
}
void get_path(int t) {
  while (t != -1) {
    usedp[t][prv[t]] = true;
    usedp[prv[t]][t] = true;
    t = prv[t];
  }
}
int main() {
  cin >> n >> m;
  int inp1, inp2, inp3;
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (n); ++j) cost[i][j] = INF;
  for (int i = 0; i < (m); ++i) {
    cin >> inp1 >> inp2 >> inp3;
    cost[inp1 - 1][inp2 - 1] = inp3;
    cost[inp2 - 1][inp1 - 1] = inp3;
  }
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (n); ++j) usedp[i][j] = false;
  for (int i = 0; i < (n); ++i) dijkstra(i);
  for (int i = 0; i < (n); ++i) get_path(i);
  int ans = 0;
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      if (usedp[i][j] == false && cost[i][j]) ans++;
    }
  }
  cout << ans << endl;
  return 0;
}
