#include <bits/stdc++.h>
using namespace std;
struct edge {
  struct treev* to;
  long long length;
  bool record;
  int num;
};
struct treev {
  int num;
  vector<edge> nexts;
};
struct input {
  int u;
  int v;
  long long w;
};
bool cmp(const input& a, const input& b) {
  if (a.u != b.u) {
    return a.u < b.u;
  } else {
    return a.v < b.v;
  }
}
vector<bool> erecord;
vector<treev*> vs;
treev* createtreenode(int num) {
  treev* newt = new treev;
  if (newt == NULL) {
    cout << "memory error" << endl;
    while (1) {
      num = 1;
    }
  }
  newt->num = num;
  newt->nexts = {};
  return newt;
}
void insertree(long long len, int Va, int Vb, int num) {
  vs[Va]->nexts.push_back({vs[Vb], len, false, num});
  vs[Vb]->nexts.push_back({vs[Va], len, false, num});
  return;
}
void DFS(treev* root, long long depth, treev* pre) {
  for (auto i : root->nexts) {
    if (pre == i.to) {
      continue;
    }
    DFS(i.to, depth + i.length, root);
  }
  return;
}
deque<tuple<treev*, long long, deque<edge>>> opera;
vector<vector<deque<edge>>> path;
vector<long long> lens;
long long g, s;
void BFS(treev* pre) {
  if (opera.size() == 0) return;
  treev* root = get<0>(opera.front());
  long long depth = get<1>(opera.front());
  if (depth > lens[root->num]) return;
  deque<edge> tmp = get<2>(opera.front());
  if (g == root->num) {
    path[s][g] = tmp;
    return;
  }
  opera.pop_front();
  for (auto i : root->nexts) {
    if (pre == i.to) {
      continue;
    }
    tmp.push_back(i);
    opera.push_back({i.to, depth + i.length, tmp});
    tmp.pop_back();
  }
  BFS(root);
  return;
}
int main(void) {
  long long n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    vs.push_back(createtreenode(i));
    lens.push_back(9999999999);
  }
  path = vector<vector<deque<edge>>>(n, vector<deque<edge>>(n, deque<edge>(0)));
  for (int i = 0; i < m; i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    erecord.push_back(false);
    insertree(c, a - 1, b - 1, i);
  }
  for (int i = 0; i <= n - 2; i++) {
    for (int j = i + 1; j < n; j++) {
      g = j;
      s = i;
      for (int k = 0; k < n; k++) {
        path[k] = {};
        lens[k] = 9999999999;
      }
      opera.push_back({vs[s], 0, {}});
      BFS(NULL);
    }
  }
  for (int i = 0; i <= n - 2; i++) {
    for (int j = i + 1; j < n; j++) {
      for (auto itr = path[i][j].begin(); itr != path[i][j].end(); ++itr) {
        erecord[itr->num] = true;
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < m; i++) {
    if (erecord[i] == false) ans++;
  }
  cout << ans << endl;
  return 0;
}
