#include <bits/stdc++.h>
const int INF = 1e9;
const int MOD = 1e9 + 7;
const long long LINF = 1e18;
using namespace std;
void CINT() {}
template <class Head, class... Tail>
void CINT(Head&& head, Tail&&... tail) {
  cin >> head;
  CINT(move(tail)...);
}
class Dijkstra {
 public:
  Dijkstra(vector<map<int, int>> ed, int firs, int pnum);
  void Solve();
  vector<int> range;
  vector<map<int, int>> edges;
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      que;
};
Dijkstra::Dijkstra(vector<map<int, int>> ed, int firs, int pnum) {
  edges = ed;
  vector<int> ttt(pnum, INF);
  range = ttt;
  range[firs] = 0;
  que.push(make_pair(0, firs));
}
void Dijkstra::Solve() {
  while (!que.empty()) {
    pair<int, int> top_ = que.top();
    que.pop();
    for (auto&(x) : (edges[top_.second])) {
      if (range[x.first] > range[top_.second] + x.second) {
        range[x.first] = range[top_.second] + x.second;
        que.push(make_pair(range[x.first], x.first));
      }
    }
  }
}
int main() {
  int n, m;
  CINT(n, m);
  vector<int> a(m);
  vector<int> b(m);
  vector<int> c(m);
  for (int i = 0; i < (m); ++i) {
    cin >> a[i] >> b[i] >> c[i];
    a[i]--;
    b[i]--;
    c[i]--;
  }
  vector<map<int, int>> edges(n);
  for (int i = 0; i < (m); ++i) {
    edges[a[i]][b[i]] = c[i];
    edges[b[i]][a[i]] = c[i];
  }
  vector<Dijkstra> start;
  for (int i = 0; i < (n); ++i) {
    start.push_back(Dijkstra(edges, i, n));
    start[i].Solve();
  }
  set<int> ans;
  for (int i = 0; i < (m); ++i) ans.insert(i);
  for (auto&(i) : (ans)) {
    vector<map<int, int>> cop = edges;
    cop[a[i]].erase(b[i]);
    cop[b[i]].erase(a[i]);
    for (int j = 0; j < (n); ++j) {
      Dijkstra copp(cop, j, n);
      copp.Solve();
      if (start[j].range != copp.range) {
        ans.erase(i);
        break;
      }
    }
  }
  cout << (ans.size()) << endl;
  return 0;
}
