#include <bits/stdc++.h>
using namespace std;
template <class T>
bool umax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool umin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
T gcd(T a, T b) {
  if (a == 0) return b;
  return gcd(b % a, a);
}
int findGCD(int arr[], int n) {
  int result = arr[0];
  for (int i = 1; i < n; i++) result = gcd(arr[i], result);
  return result;
}
template <typename T>
T lcm(T m, T n) {
  if ((0 == m) || (0 == n)) return 0;
  return ((m / gcd(m, n)) * n);
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  fill((T *)array, (T *)(array + N), val);
}
int dx[5] = {1, 0, -1, 0};
int dy[5] = {0, 1, 0, -1};
int N;
int d[110][110];
void warshall_floyd() {
  for (int k = 0; k < N; k++) {
    for (int i = 0; i < N; ++i) {
      for (int j = 0; j < N; ++j) {
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
}
int main() {
  int M;
  cin >> N >> M;
  vector<int> A(N), B(N), C(N);
  for (int i = 0; i < (int)(M); i++) {
    cin >> A[i] >> B[i] >> C[i];
    A[i]--, B[i]--;
  }
  Fill(d, 1000000);
  for (int i = 0; i < N; i++) {
    d[i][i] = 0;
  }
  for (int i = 0; i < M; i++) {
    d[A[i]][B[i]] = min(d[A[i]][B[i]], C[i]);
    d[B[i]][A[i]] = min(d[B[i]][A[i]], C[i]);
  }
  warshall_floyd();
  int ans = M;
  for (int i = 0; i < M; i++) {
    bool flag = false;
    for (int j = 0; j < N; j++) {
      if (d[j][A[i]] + C[i] == d[j][B[i]]) flag = true;
    }
    if (flag) {
      ans--;
    }
  }
  cout << ans << endl;
  return 0;
}
