#include <bits/stdc++.h>
using namespace std;
struct edge {
  int to, cost;
  edge(int t, int c) : to(t), cost(c) {}
};
int n, m;
int d[1001][101];
vector<vector<edge> > G(101);
void dijkstra(int s, int *d) {
  priority_queue<pair<int, int>, vector<pair<int, int> >,
                 greater<pair<int, int> > >
      que;
  fill(d, d + 101, 1000000);
  d[s] = 0;
  que.push(pair<int, int>(0, s));
  while (!que.empty()) {
    pair<int, int> p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first) continue;
    for (int i = 0; i < G[v].size(); i++) {
      edge e = G[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(pair<int, int>(d[e.to], e.to));
      }
    }
  }
}
int main(void) {
  int n, m;
  cin >> n >> m;
  vector<int> a(n), b(n), c(n);
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i] >> c[i];
    G[a[i] - 1].push_back(edge(b[i] - 1, c[i]));
    G[b[i] - 1].push_back(edge(a[i] - 1, c[i]));
  }
  dijkstra(0, d[0]);
  for (int i = 0; i < m; i++) {
    G.clear();
    G.resize(101);
    for (int j = 0; j < m; j++) {
      if (j == i) continue;
      G[a[j] - 1].push_back(edge(b[j] - 1, c[j]));
      G[b[j] - 1].push_back(edge(a[j] - 1, c[j]));
    }
    dijkstra(0, d[i + 1]);
  }
  int ans = 0;
  for (int i = 1; i <= m; i++) {
    for (int j = 0; j < n; j++) {
      if (d[i][j] != d[0][j]) break;
      if (j == n - 1) ans++;
    }
  }
  cout << ans << endl;
  return 0;
}
