#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll INF = (ll)1e18;
constexpr ll MOD = (ll)1e9 + 7;
constexpr double EPS = 1e-9;
constexpr ll dx[4] = {1LL, 0LL, -1LL, 0LL};
constexpr ll dy[4] = {0LL, 1LL, 0LL, -1LL};
constexpr ll dx8[8] = {1LL, 0LL, -1LL, 0LL, 1LL, 1LL, -1LL, -1LL};
constexpr ll dy8[8] = {0LL, 1LL, 0LL, -1LL, 1LL, -1LL, 1LL, -1LL};
void p() { std::cout << '\n'; }
template <typename Head, typename... Tail>
void p(Head head, Tail... tail) {
  std::cout << head << (sizeof...(tail) ? " " : "");
  p(tail...);
}
template <typename T>
inline void pv(std::vector<T>& v) {
  for (ll i = 0, N = v.size(); i < N; i++)
    std::cout << v[i] << " \n"[i == N - 1];
}
template <typename T>
inline T gcd(T a, T b) {
  return b ? gcd(b, a % b) : a;
}
template <typename T>
inline T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
template <typename T>
inline bool chmax(T& a, T b) {
  return a < b && (a = b, true);
}
template <typename T>
inline bool chmin(T& a, T b) {
  return a > b && (a = b, true);
}
template <typename T>
inline void uniq(std::vector<T>& v) {
  v.erase(std::unique(v.begin(), v.end()), v.end());
}
void warshall_floyd(vector<vector<ll>>& d) {
  ll N = d.size();
  for (ll k = 0; k < N; k++) {
    for (ll i = 0; i < N; i++) {
      for (ll j = 0; j < N; j++) {
        if (d[i][k] != INF && d[k][j] != INF && d[i][k] + d[k][j] < d[i][j]) {
          d[i][j] = d[i][k] + d[k][j];
        }
      }
    }
  }
}
void solve() {
  ll N, M;
  cin >> N >> M;
  vector<vector<ll>> d(N, vector<ll>(N, INF));
  for (ll i = 0; i < N; i++) d[i][i] = 0;
  vector<ll> a(N), b(N), c(N);
  for (ll i = 0; i < M; i++) {
    ll from, to, cost;
    cin >> from >> to >> cost;
    from--;
    to--;
    a[i] = from;
    b[i] = to;
    c[i] = cost;
    d[from][to] = cost;
    d[to][from] = cost;
  }
  warshall_floyd(d);
  ll ans = 0;
  for (ll i = 0, i_length = (M); i < i_length; ++i) {
    if (d[a[i]][b[i]] < c[i]) ans++;
  }
  p(ans);
}
signed main() {
  solve();
  return 0;
}
