#include <bits/stdc++.h>
using namespace std;
struct Vertex;
struct Edge {
  int w;
  Vertex *s, *t;
};
struct Vertex {
  int n;
  vector<Edge*> neighbor;
  int d = INT_MAX;
  Vertex* pre = NULL;
  int visited = 0;
};
struct comparator {
  bool operator()(Vertex* p1, Vertex* p2) { return p1->d > p2->d; }
};
void djs(vector<Vertex*> v, int s) {
  vector<Vertex*> pq(v);
  pq[s]->d = 0;
  make_heap(pq.begin(), pq.end(), comparator());
  while (pq.size() > 0) {
    Vertex* sv = pq.front();
    sv->visited = 1;
    pop_heap(pq.begin(), pq.end(), comparator());
    pq.pop_back();
    for (auto e : sv->neighbor) {
      Vertex* tv = e->t;
      if (tv->visited) continue;
      if (sv->d + e->w < tv->d) {
        tv->d = sv->d + e->w;
        tv->pre = sv;
      }
    }
    make_heap(pq.begin(), pq.end(), comparator());
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  vector<Vertex*> v;
  map<pair<int, int>, bool> mark;
  for (int i = 1; i <= n; i++) {
    Vertex* v1 = new Vertex();
    v1->n = i;
    v.push_back(v1);
  }
  for (int i = 0; i < m; i++) {
    int s, t, w;
    cin >> s >> t >> w;
    Vertex* sv = v[s - 1];
    Vertex* tv = v[t - 1];
    Edge* e = new Edge();
    e->s = sv;
    e->t = tv;
    e->w = w;
    sv->neighbor.push_back(e);
    Edge* e1 = new Edge();
    e1->s = tv;
    e1->t = sv;
    e1->w = w;
    tv->neighbor.push_back(e1);
    mark[make_pair(s, t)] = false;
    mark[make_pair(t, s)] = false;
  }
  for (int i = 0; i < n; i++) {
    for (auto v1 : v) {
      v1->d = INT_MAX;
      v1->pre = NULL;
      v1->visited = 0;
    }
    djs(v, i);
    for (auto v1 : v) {
      Vertex* travel = v1;
      while (travel->pre != NULL) {
        int t = travel->n;
        int s = travel->pre->n;
        mark[make_pair(s, t)] = true;
        mark[make_pair(t, s)] = true;
        travel = travel->pre;
      }
    }
  }
  int out = 0;
  for (auto m : mark) {
    if (m.second == false) out++;
  }
  cout << out / 2 << endl;
  return 0;
}
