#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
const long long INF = 1e9 + 7;
bool used[100][100];
bool fin[100][100];
pair<long long, long long> d[100][100];
void dfs(long long s, long long t) {
  if (fin[s][t] || fin[t][s]) return;
  if (d[s][t].first == -1) {
    used[s][t] = true;
    used[t][s] = true;
    fin[s][t] = true;
    fin[t][s] = true;
    return;
  }
  fin[s][t] = true;
  fin[t][s] = true;
  dfs(s, d[s][t].first);
  dfs(d[s][t].first, t);
  return;
}
int main() {
  long long n, m;
  cin >> n >> m;
  vector<pair<long long, long long> > edge(m);
  for (long long i = 0; i < (m); i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    d[a][b] = make_pair(-1, c);
    d[b][a] = make_pair(-1, c);
    edge[i] = make_pair(a, b);
  }
  for (long long k = 0; k < (n); k++) {
    for (long long i = 0; i < (n); i++) {
      for (long long j = 0; j < (n); j++) {
        if (d[i][j].second > d[i][k].second + d[k][j].second) {
          d[i][j] = make_pair(k, d[i][k].second + d[k][j].second);
        }
      }
    }
  }
  for (long long i = 0; i < (n); i++) {
    for (long long j = 0; j < (n); j++) {
      if (i == j) continue;
      dfs(i, j);
    }
  }
  long long ans = m;
  for (long long i = 0; i < (m); i++) {
    if (used[edge[i].first][edge[i].second]) ans--;
  }
  cout << ans << endl;
  return 0;
}
