#include <bits/stdc++.h>
using namespace std;
template <typename T = long long>
inline T IN() {
  T x;
  cin >> x;
  return (x);
}
inline void CIN() {}
template <class Head, class... Tail>
inline void CIN(Head &&head, Tail &&...tail) {
  cin >> head;
  CIN(move(tail)...);
}
template <typename T = string>
inline void eputs(T s) {
  cout << s << "\n";
  exit(0);
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
template <typename T>
using PQG = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using PQ = priority_queue<T>;
const long long INF = 1e9;
const long long MOD = 1e9 + 7;
const long long LINF = 1e18;
const long long dx[] = {1, 0, -1, 0};
const long long dy[] = {0, 1, 0, -1};
long long N, M, a[1000], b[1000], c[1000];
long long d[100][100];
bool notneed[100][100];
void warshall_floyd() {
  for (long long i = 0; i < (N); ++i) d[i][i] = 0;
  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] > d[i][k] + d[k][j]) {
          notneed[i][j] = true;
          notneed[j][i] = true;
        }
      }
}
signed main() {
  cin >> N >> M;
  Fill(d, LINF);
  for (long long i = 0; i < (M); ++i) {
    cin >> a[i] >> b[i] >> c[i];
    d[--a[i]][--b[i]] = c[i];
    d[b[i]][a[i]] = c[i];
  }
  warshall_floyd();
  long long ans = 0;
  for (long long i = 0; i < (M); ++i)
    if (notneed[a[i]][b[i]]) ans++;
  cout << ans << "\n";
}
