#include <bits/stdc++.h>

template <typename InputIterator>
typename InputIterator::value_type summation(InputIterator first,
                                             InputIterator last) {
  return std::accumulate(first, last, typename InputIterator::value_type());
}
template <typename T>
std::istream &operator>>(std::istream &stream, std::vector<T> &v);
template <typename T1, typename T2>
std::istream &operator>>(std::istream &stream, std::pair<T1, T2> &p);
template <typename T>
std::istream &operator>>(std::istream &stream, std::vector<T> &v) {
  for (auto &i : v) {
    stream >> i;
  }
  return stream;
}
template <typename T1, typename T2>
std::istream &operator>>(std::istream &stream, std::pair<T1, T2> &p) {
  stream >> p.first >> p.second;
  return stream;
}

int main() {
  int n, m;
  std::cin >> n >> m;
  std::vector<std::map<int, int>> no(n);
  std::set<std::pair<int, int>> ans;

  for (int i = 0; i < m; i++) {
    int a, b, c;
    std::cin >> a >> b >> c;
    a--;
    b--;
    no[b].insert({a, c});
    no[a].insert({b, c});
    ans.insert({a, b});
  }

  for (int i = 0; i < n; i++) {
    std::vector<int> f(n, -1);
    f[i] = 0;
    std::multimap<int, std::pair<int, int>> q;
    for (const auto j : no[i]) {
      q.insert({j.second, {i, j.first}});
    }
    while (!std::all_of(f.cbegin(), f.cend(), [](auto i) { return i != -1; })) {
      const auto &tmp = *q.cbegin();
      const auto cost = tmp.first;
      const auto before = tmp.second.first;
      const auto now = tmp.second.second;
      if (f[now] == -1 || cost <= f[now]) {
        f[now] = cost;
        ans.erase({now, before});
        ans.erase({before, now});
        for (const auto k : no[now]) {
          const auto next = k.first;
          const auto next_cost = cost + k.first;
          if (f[next] == -1 || next_cost <= f[next]) {
            f[next] = next_cost;
            q.insert({next_cost, {now, next}});
          }
        }
      }
      q.erase(q.begin());
    }
  }
  std::cout << ans.size() << std::endl;
  return 0;
}