#include <bits/stdc++.h> 

using namespace std; 
using ll = long long;
using ull = unsigned long long;
using pii = pair<int,int>; 

#define INF 100000000
#define MOD 10007
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()

struct Graph{
  int from,to,cost;
  bool operator <(Graph a){
    return (cost<a.cost);
  }
};

struct UnionFindTree{
  vector<int>par,rank;

  UnionFindTree(int n){
    par.resize(n);
    rank.resize(n);
    for(int i=0;i<n;i++){
      par[i]=i;
      rank[i]=0;
    }
  }

  int find(int x){
    if(par[x]==x)return x;
    else return par[x]=find(par[x]);
  }

  void unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)return;
    if(rank[x]<rank[y]){
      par[x]=y;
    }
    else{
      par[y]=x;
      if(rank[x]==rank[y])rank[x]++;
    }
  }

  bool same(int x,int y){
    return find(x)==find(y);
  }

};

int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);

  int N,M;
  cin>>N>>M;
  vector<Graph>e(M);
  for(int i=0;i<M;i++){
    int a,b,c;
    cin>>a>>b>>c;
    e[i].from=a;
    e[i].to=b;
    e[i].cost=c;
  }
  UnionFindTree uf(N+1);
  sort(rng(e));
  int ans=0;
  //for(auto it:e)cout<<it.from<<endl;
  for(int i=0;i<M;i++){
    int to=e[i].to;
    int from=e[i].from;
    if(uf.same(from,to))continue;
    else{
      uf.unite(from,to);
      ans++;
    }
  }
  cout<<M-ans<<endl;
  return 0;
}
