#include <bits/stdc++.h>
using namespace std;
const long long MAX_N = 110;
const long long INF = 1e12;
vector<pair<long long, long long> > g[MAX_N];
long long d[MAX_N];
int n;
bool used[MAX_N][MAX_N];
int pr[MAX_N];
void dijkstra(int s) {
  priority_queue<pair<long long, long long>,
                 vector<pair<long long, long long> >,
                 greater<pair<long long, long long> > >
      PQ;
  for (int i = 1; i <= n; i++) d[i] = INF;
  for (int i = 1; i <= n; i++) pr[i] = -1;
  d[s] = 0;
  PQ.push(make_pair(0, s));
  while (!PQ.empty()) {
    pair<long long, long long> p = PQ.top();
    PQ.pop();
    int v = p.second;
    if (d[v] < p.first) continue;
    for (auto gvi : g[v]) {
      long long cost = gvi.first;
      int u = gvi.second;
      if (d[u] > d[v] + cost) {
        d[u] = d[v] + cost;
        PQ.push(make_pair(d[u], u));
        pr[u] = v;
      }
    }
  }
}
void get_path(int t) {
  for (; t != -1; t = pr[t]) {
    used[t][pr[t]] = true;
    used[pr[t]][t] = true;
  }
}
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  int m;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      used[i][j] = true;
    }
  }
  for (int i = 0; i < m; i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    g[a].push_back(make_pair(c, b));
    g[b].push_back(make_pair(c, a));
    used[a][b] = false;
    used[b][a] = false;
  }
  for (int i = 1; i <= n; i++) {
    dijkstra(i);
    for (int j = i + 1; j <= n; j++) {
      get_path(j);
    }
  }
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = i + 1; j <= n; j++) {
      if (used[i][j] == false) cnt++;
    }
  }
  cout << cnt << endl;
}
