#include <bits/stdc++.h>
using namespace std;
class SplitStream {
  std::ostream& ost_m;
  bool line_is_empty_m;

 public:
  SplitStream(std::ostream& ost);
  template <typename T>
  SplitStream& operator<<(T right);
  SplitStream& operator<<(basic_ostream<char, char_traits<char>>& (*right)(
      basic_ostream<char, char_traits<char>>&));
};
SplitStream::SplitStream(std::ostream& ost)
    : ost_m(ost), line_is_empty_m(true) {}
template <typename T>
SplitStream& SplitStream::operator<<(T right) {
  if (!line_is_empty_m) ost_m << ' ';
  line_is_empty_m = false;
  ost_m << right;
  return *this;
}
SplitStream& SplitStream::operator<<(basic_ostream<char, char_traits<char>>& (
    *right)(basic_ostream<char, char_traits<char>>&)) {
  ost_m << '\n';
  ost_m.flush();
  line_is_empty_m = true;
  return *this;
}
SplitStream Scout(cout);
template <typename T, int Begin, int End>
class OffsetArray {
  T arr_m[End - Begin];

 public:
  OffsetArray();
  T& operator[](int index);
  T operator[](int index) const;
};
template <typename T, int Begin, int End>
OffsetArray<T, Begin, End>::OffsetArray() : arr_m() {}
template <typename T, int Begin, int End>
T& OffsetArray<T, Begin, End>::operator[](int index) {
  return arr_m[index - Begin];
}
template <typename T, int Begin, int End>
T OffsetArray<T, Begin, End>::operator[](int index) const {
  return arr_m[index - Begin];
}
template <typename T, int N>
void Fill(T (&arr)[N], T val) {
  for (int i = 0; i < N; ++i) {
    arr[N] = val;
  }
}
template <typename T, int M, int N>
void Fill(T (&arr)[M][N], T val) {
  for (int i = 0; i < M; ++i) {
    Fill(arr[i], val);
  }
}
template <typename T>
using PriorityQ = priority_queue<T, vector<T>, greater<T>>;
int N, M;
int A[1000], B[1000], C[1000];
int D[100][100];
int main() {
  cin >> N >> M;
  for (int i = 0; i < M; ++i) {
    cin >> A[i] >> B[i] >> C[i];
    --A[i];
    --B[i];
  }
  Fill(D, 0x3FFFFFFF);
  for (int i = 0; i < M; ++i) {
    D[A[i]][B[i]] = C[i];
    D[B[i]][A[i]] = C[i];
  }
  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 cnt = 0;
  for (int i = 0; i < M; ++i) {
    if (C[i] > D[A[i]][B[i]]) ++cnt;
  }
  cout << cnt << endl;
  return 0;
}
