#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
using LP = pair<ll, ll>;
template <class T>
istream& operator>>(istream& is, vector<T>& v) {
  for (T& t : v) {
    is >> t;
  }
  return is;
}
template <class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
  for (int i = 0; i < (v.size()); ++i)
    os << v[i] << (i == v.size() - 1 ? "\n" : " ");
  return os;
}
void Yes(bool b) { cout << (b ? "Yes" : "No") << endl; }
void YES(bool b) { cout << (b ? "YES" : "NO") << endl; }
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
const int inf = 1001001001;
const ll linf = 1001001001001001001;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int n, m;
  cin >> n >> m;
  vector<vector<int>> dist(n, vector<int>(n, inf));
  for (int i = 0; i < (n); ++i) dist[i][i] = 0;
  vector<tuple<int, int, int>> v;
  for (int _ = 0; _ < (m); ++_) {
    int a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    dist[a][b] = c;
    dist[b][a] = c;
    v.emplace_back(a, b, c);
  }
  for (int k = 0; k < (n); ++k)
    for (int i = 0; i < (n); ++i)
      for (int j = 0; j < (n); ++j) {
        chmin(dist[i][j], dist[i][k] + dist[k][j]);
      }
  int ans = 0;
  for (auto [a, b, c] : v) {
    bool ok = true;
    for (int i = 0; i < (n); ++i)
      for (int j = 0; j < (n); ++j) {
        if (dist[i][j] == dist[i][a] + c + dist[b][j]) ok = false;
        if (dist[i][j] == dist[i][b] + c + dist[a][j]) ok = false;
      }
    if (ok) ans++;
  }
  cout << ans << endl;
}
