#include <bits/stdc++.h>
using namespace std;
struct edge {
  int to, cost, id;
};
const int inf = 1000000001;
int n, d[100];
vector<int> PREV[100];
vector<edge> g[100];
void dijkstra(int v) {
  priority_queue<pair<int, int>, vector<pair<int, int> >,
                 greater<pair<int, int> > >
      q;
  fill(d, d + n, inf);
  for (int u = 0; u < n; ++u) PREV[u].clear();
  d[v] = 0;
  q.push(make_pair(0, v));
  while (!q.empty()) {
    int D = q.top().first, w = q.top().second;
    q.pop();
    if (D > d[w]) {
      continue;
    }
    for (int j = 0; j < g[w].size(); ++j) {
      int u = g[w][j].to, c = g[w][j].cost, id = g[w][j].id;
      if (d[u] > D + c) {
        d[u] = D + c;
        q.push(make_pair(d[u], u));
        PREV[u].clear();
      }
      if (d[u] >= D + c) {
        PREV[u].push_back(id);
      }
    }
  }
}
int main() {
  int m;
  cin >> n >> m;
  for (int j = 1; j <= m; ++j) {
    int a, b, c;
    cin >> a >> b >> c;
    g[--a].push_back((edge){--b, c, j});
    g[b].push_back((edge){a, c, j});
  }
  bool f[1000 + 1];
  fill(f, f + m, false);
  for (int v = 0; v < n; ++v) {
    dijkstra(v);
    for (int w = 0; w < n; ++w)
      for (int j = 0; j < PREV[w].size(); ++j) {
        f[PREV[w][j]] = true;
      }
  }
  int ans = 0;
  for (int j = 1; j <= m; ++j)
    if (!f[j]) ++ans;
  cout << ans << endl;
}
