stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<iostream>

#include<vector>

using namespace std;



const int MAX_N = 1e5 + 1;

const int MAX_M = 1e5 + 1;



int color[MAX_N];

vector<int> graph[MAX_N];



void dfs(int node, int c) {

    color[node] = c;

    for (int i = 0; i < graph[node].size(); i++) {

        if (color[graph[node][i]]) continue;

        dfs(graph[node][i], c);

    }

}



int main() {

    cin.tie(0);

    ios::sync_with_stdio(false);

    int N, M;

    cin >> N >> M;

    int x, y, z;

    for (int i = 0; i < M; i++) {

        cin >> x >> y >> z;

        x--, y--;

        graph[x].push_back(y);

        graph[y].push_back(x);

    }

    int now_color = 1;

    for (int i = 0; i < N; i++) {

        if (color[i]) continue;

        dfs(i, now_color);

        now_color++;

    }

    cout << now_color - 1 << endl;

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.3002682564341024x):
#include<iostream>

#include<vector>

#include<string>

#define rep(i, start, end) for (int i = (int)start; i < (int)end; ++i)

#define rrep(i, start, end) for (int i = (int)start - 1; i >= (int)end; --i)

#define all(x) (x).begin(), (x).end()

using namespace std;

using ll = long long;

template<typename T> inline bool chmax(T& a, T b) {if (a < b) {a = b; return true;} return 0;}

template<typename T> inline bool chmin(T& a, T b) {if (a > b) {a = b; return true;} return 0;}



void dfs(const vector<vector<int>>& graph, vector<bool>& visited, int node) {

    visited[node] = true;

    for (auto& next_node : graph[node]) {

        if (!visited[next_node]) {

            dfs(graph, visited, next_node);

        }

    }

}



int main() {

    cin.tie(0);

    ios::sync_with_stdio(false);

    int N, M;

    cin >> N >> M;

    vector<int> X(M), Y(M), Z(M);

    rep(i, 0, M) {

        cin >> X[i] >> Y[i] >> Z[i];

        --X[i], --Y[i];

    }

    vector<vector<int>> graph(N);

    rep(i, 0, M) {

        graph[X[i]].push_back(Y[i]);

        graph[Y[i]].push_back(X[i]);

    }

    int ans = 0;

    vector<bool> visited(N, false);

    rep(i, 0, N) {

        if (!visited[i]) {

            dfs(graph, visited, i);

            ++ans;

        }

    }

    cout << ans << endl;

    return 0;

}
// Slower C++ solution:
#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>

using namespace std;

template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;} return 0;}

template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;} return 0;}

#define rep(i,n) for(int i=0;i<(int)(n);i++)

#define all(vec) vec.begin(),vec.end()

typedef long long ll;

typedef pair<ll,ll> l_l;

typedef pair<int,int> i_i;

const ll mod=1e9+7;

const int inf=1<<30;



struct unionfind{

  vector<int> par;

  vector<int> rank;

  unionfind(int n=1){

    init(n);

  }

  void init(int n=1){

      par.resize(n); rank.resize(n);

      for(int i=0;i<n;++i) par[i]=i,rank[i]=0;

  }

  int root(int x){

    if(par[x]==x){

      return x;

    }

    else{

      int r=root(par[x]);

      return par[x]=r;

    }

  }

  bool issame(int x,int y){

    return root(x)==root(y);

  }

  bool merge(int x,int y){

    x=root(x); y=root(y);

    if(x==y) return false;

    if(rank[x]<rank[y]) swap(x,y);

    if(rank[x]==rank[y]) ++rank[x];

    par[y]=x;

    return true;

  }

};



int main(){

  unionfind uf(1e5);

  int n,m; cin >> n >> m;

  rep(i,m){

    int a,b,c;

     cin >> a >> b >> c;

     a--; b--;

    uf.merge(a,b);

  }

  set<int> st;

  rep(i,n){

    st.insert(uf.root(i));

  }

  cout << st.size() << endl;

}

// Faster C++ solution for the same problem (measured speedup: 1.9889791938362655x):
#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>

using namespace std;

template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;} return 0;}

template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;} return 0;}

#define rep(i,n) for(int i=0;i<(int)(n);i++)

#define all(vec) vec.begin(),vec.end()

typedef long long ll;

typedef pair<ll,ll> pll;

typedef pair<int,int> pii;

const ll mod=1e9+7;

const int inf=1<<30;



struct unionfind{

  vector<int> par;

  vector<int> rank;

  unionfind(int n=1){

    init(n);

  }

  void init(int n=1){

      par.resize(n); rank.resize(n);

      for(int i=0;i<n;++i) par[i]=i,rank[i]=0;

  }

  int root(int x){

    if(par[x]==x){

      return x;

    }

    else{

      int r=root(par[x]);

      return par[x]=r;

    }

  }

  bool issame(int x,int y){

    return root(x)==root(y);

  }

  bool merge(int x,int y){

    x=root(x); y=root(y);

    if(x==y) return false;

    if(rank[x]<rank[y]) swap(x,y);

    if(rank[x]==rank[y]) ++rank[x];

    par[y]=x;

    return true;

  }

};



int main(){

  int n,m; cin >> n >> m;

  unionfind uf(n);

  rep(i,m){

    int a,b,c;

    cin >> a >> b >> c;

    a--; b--;

    uf.merge(a,b);

  }

  map<int,int> mp;

  rep(i,n){

    mp[uf.root(i)]++;

  }

  cout << mp.size() << endl;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



int n, m;

const int N = 100010;

vector<int> G[N];

vector<bool> seen(N);



void dfs(int now){

    seen[now] = true;

    for(int i = 0; i < G[now].size(); i++){

        int to = G[now][i];

        if(seen[to]) continue;

        dfs(to);

    }

}



int main(){

    cin.tie(nullptr);

    ios::sync_with_stdio(false);



    cin >> n >> m;

    for(int i = 0; i < m; i++){

        int x, y, z;

        cin >> x >> y >> z;

        x--; y--;

        G[x].push_back(y);

        G[y].push_back(x);

    }



    int ans = 0;

    for(int i = 0; i < n; i++){

        if(!seen[i]){

            dfs(i);

            ans++;

        }

    }



    cout << ans << endl;



    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.4896389003701094x):
#include <bits/stdc++.h>

using namespace std;



struct UnionFind{

    vector<int> par;

    UnionFind(int N) : par(N){

        for(int i = 0; i < N; i++){

            par[i] = -1;

        }

    }

    int root(int x){

        if(par[x] < 0) return x;

        else return par[x] = root(par[x]);

    }

    void unite(int x, int y){

        int rx = root(x);

        int ry = root(y);

        if(rx == ry) return;

        else{

            if(par[rx] > par[ry]) swap(rx, ry);

            par[rx] += par[ry];

            par[ry] = rx;

       }

    }

    bool same(int x, int y){

        return root(x) == root(y);

    }

    void check(){

        for(auto x : par){

            cout << x << " ";

        }

        cout << endl;

    }

};



int main(){

    cin.tie(nullptr);

    ios::sync_with_stdio(false);



    int n, m;

    cin >> n >> m;



    UnionFind uf(n);

    for(int i = 0; i < m; i++){

        int a, b, x;

        cin >> a >> b >> x;

        a--; b--;

        uf.unite(a, b);

    }



    set<int> st;

    for(int i = 0; i < n; i++){

        st.insert(uf.root(i));

    }



    cout << st.size() << endl;





    return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

vector<vector<int>> adj(100001);

int ret=0;

vector<bool> vu(100001);



void dfs(int node){

	for (auto& i:adj[node]){

		if (!vu[i]){

			vu[i]=true;

			dfs(i);

		}

	}

}



int main(){

	int n,m;

	cin >> n >> m;

	for (int i=0; i<m; ++i){

		int a,b,c;

		cin >> a >> b >> c;

		adj[a].emplace_back(b);

		adj[b].emplace_back(a);

	}

	for (int i=1; i<=n; ++i){

		if (!vu[i]){

			vu[i]=true;

			++ret;

			dfs(i);

		}

	}

	cout << ret;

}


// Faster C++ solution for the same problem (measured speedup: 2.5492742553830183x):
#include <iostream>

#include <vector>

using namespace std;



vector<int> comp(100001);



int find_comp(int a){

	int compa=comp[a];

	while (compa != comp[compa]) compa=comp[compa];

	comp[a]=compa;

	return compa;

}



int main(){

	int n,m;

	cin >> n >> m;

	int cnt=n;

	for (int i=1; i<=n; ++i) comp[i]=i;

	for (int i=0; i<m; ++i){

		int x,y,z;

		cin >> x >> y >> z;

		int a=find_comp(x),b=find_comp(y);

		if (a != b){

			comp[b]=a;

			--cnt;

		}

	}

	cout << cnt;

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

vector<vector<int>> adj(100001);

int ret=0;

vector<bool> vu(100001);



void dfs(int node){

	for (auto& i:adj[node]){

		if (!vu[i]){

			vu[i]=true;

			dfs(i);

		}

	}

}



int main(){

	int n,m;

	cin >> n >> m;

	for (int i=0; i<m; ++i){

		int a,b,c;

		cin >> a >> b >> c;

		adj[a].emplace_back(b);

		adj[b].emplace_back(a);

	}

	for (int i=1; i<=n; ++i){

		if (!vu[i]){

			vu[i]=true;

			++ret;

			dfs(i);

		}

	}

	cout << ret;

}


// Faster C++ solution for the same problem (measured speedup: 3.49048111945241x):
#include <bits/stdc++.h>

using namespace std;

int getComp(vector<int>& comp,int i){

  if(comp[i] != i) comp[i] = getComp(comp,comp[i]);

  return comp[i];

}

void merge(vector<int>& comp,vector<int>& level,int a,int b){

  a = getComp(comp,a);

  b = getComp(comp,b);

  if(level[a] > level[b]) swap(a,b);

  else if(level[a] == level[b]) ++level[b];

  comp[a] = b;

}

int main(){

  ios::sync_with_stdio(0);

  cin.tie(0);

  int n,m,x,y,z;

  cin >> n >> m;

  vector<int> comp(n+1),level(n+1);

  iota(begin(comp),end(comp),0);

  while(m--){

    cin >> x >> y >> z;

    merge(comp,level,x,y);

  }

  set<int> st;

  for(int i = 1; i <= n; ++i) st.insert(getComp(comp,i));

  cout << st.size();

  return 0;

}
// Slower C++ solution:
#include <iostream>

#include <vector>

using namespace std;



vector<int> comp(100001);



int find_comp(int a){

	int compa=comp[a];

	while (compa != comp[compa]) compa=comp[compa];

	comp[a]=compa;

	return compa;

}



int main(){

	int n,m;

	cin >> n >> m;

	int cnt=n;

	for (int i=1; i<=n; ++i) comp[i]=i;

	for (int i=0; i<m; ++i){

		int x,y,z;

		cin >> x >> y >> z;

		int a=find_comp(x),b=find_comp(y);

		if (a != b){

			comp[b]=a;

			--cnt;

		}

	}

	cout << cnt;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.3708080209084035x):
#include <bits/stdc++.h>

using namespace std;

int getComp(vector<int>& comp,int i){

  if(comp[i] != i) comp[i] = getComp(comp,comp[i]);

  return comp[i];

}

void merge(vector<int>& comp,vector<int>& level,int a,int b){

  a = getComp(comp,a);

  b = getComp(comp,b);

  if(level[a] > level[b]) swap(a,b);

  else if(level[a] == level[b]) ++level[b];

  comp[a] = b;

}

int main(){

  ios::sync_with_stdio(0);

  cin.tie(0);

  int n,m,x,y,z;

  cin >> n >> m;

  vector<int> comp(n+1),level(n+1);

  iota(begin(comp),end(comp),0);

  while(m--){

    cin >> x >> y >> z;

    merge(comp,level,x,y);

  }

  set<int> st;

  for(int i = 1; i <= n; ++i) st.insert(getComp(comp,i));

  cout << st.size();

  return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

vector<vector<int>> adj(100001);

int ret=0;

vector<bool> vu(100001);



void dfs(int node){

	for (auto& i:adj[node]){

		if (!vu[i]){

			vu[i]=true;

			dfs(i);

		}

	}

}



int main(){

	int n,m;

	cin >> n >> m;

	for (int i=0; i<m; ++i){

		int a,b,c;

		cin >> a >> b >> c;

		adj[a].emplace_back(b);

		adj[b].emplace_back(a);

	}

	for (int i=1; i<=n; ++i){

		if (!vu[i]){

			vu[i]=true;

			++ret;

			dfs(i);

		}

	}

	cout << ret;

}


// Faster C++ solution for the same problem (measured speedup: 1.9035649602894154x):
#include <bits/stdc++.h>

using namespace std;



vector<int> level(100001),comp(100001);



int getComp(int i){

  if(comp[i] != i) comp[i] = getComp(comp[i]);

  return comp[i];

}



void merge(int a,int b){

  a = getComp(a);

  b = getComp(b);

  if(level[a] > level[b]) swap(a,b);

  else if(level[a] == level[b]) ++level[b];

  comp[a] = b;

}



int main(){

  ios::sync_with_stdio(0);

  cin.tie(0);

  int n,m,x,y,z;

  cin >> n >> m;

  iota(begin(comp),end(comp),0);

  while(m--){

    cin >> x >> y >> z;

    merge(x,y);

  }

  set<int> st;

  for(int i = 1; i <= n; ++i) st.insert(getComp(i));

  cout << st.size();

  return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



int N, M;

bool flag[100005] = {};

vector < int > G[100005];



void coloring(int v)

{

        if ( flag[v] ) return;

        flag[v] = true;

        

        for ( auto &x : G[v] ) {

                coloring(x);

        }

}



int main()

{

        cin >> N >> M;

        while ( M-- ) {

                int a, b, c;

                cin >> a >> b >> c; --a, --b;

                G[a].push_back(b);

                G[b].push_back(a);

        }

        

        int cnt = 0;

        for ( int i = 0; i < N; i++ ) {

                if ( !flag[i] ) {

                        cnt++;

                        coloring(i);

                }

        }



        cout << cnt << endl;



        return ( 0 );

}


// Faster C++ solution for the same problem (measured speedup: 3.301749868712629x):
#include <bits/stdc++.h>

using namespace std;



using ll = long long;

using Pi = pair<int, int>;

using Pl = pair<ll, ll>;

using vint = vector<int>;

using vvint = vector<vint>;

using vvvint = vector<vvint>;

using vdouble = vector<double>;

using vvdouble = vector<vdouble>;

using vvvdouble = vector<vvdouble>;

using vll = vector<ll>;

using vvll = vector<vll>;

using vvvll = vector<vvll>;

using uint = unsigned int;

using ull = unsigned long long;



template<typename T> using uset = unordered_set<T>;

template<typename T1, typename T2> using umap = unordered_map<T1, T2>;



constexpr int INF = (1 << 30) - 1;

constexpr ll LLINF = 1LL << 60;

constexpr int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};

constexpr int dx[] = {0, 1, 0, -1, 1, 1, -1, -1};

constexpr char el = '\n';

constexpr int mod = 1000000007;



template<typename T> T gcd(T a, T b) { return (b ? gcd(b, a % b) : a); }

template<typename T> T lcm(T a, T b) { return (a / gcd(a, b) * b); }

template<typename T1, typename T2>

inline bool chmin(T1 &a, T2 b) { return (a > b && (a = b, true)); }

template<typename T1, typename T2>

inline bool chmax(T1 &a, T2 b) { return (a < b && (a = b, true)); }



template<typename T>

ostream& operator <<(ostream &os, vector<T> &v) {

	os << v[0];

	for (int i = 1; i < v.size(); i++) os << " " << v[i];

	return (os);

}



template<typename T>

istream& operator >>(istream &is, vector<T> &v) {

	for (auto &u : v) is >> u; return (is);

}



template<typename T1, typename T2>

istream& operator >>(istream &is, pair<T1, T2> &p) {

	return (is >> p.first >> p.second);

}



vvint G;

bitset<100005> flag;



void dfs(int u) {

	if (flag[u]) return;

	flag[u] = true;

	for (auto &v : G[u]) dfs(v);

}

void Main() {

	int N, M; cin >> N >> M;

	G = vvint(N);

	while (M--) {

		int a, b, c; cin >> a >> b >> c; --a, --b;

		G[a].push_back(b);

		G[b].push_back(a);

	}

	int cnt = 0;

	for (int i = 0; i < N; i++) {

		if (!flag[i]) {

			dfs(i); cnt++;

		}

	}

	cout << cnt << endl;

}



int main() {

	cin.tie(0);

	ios::sync_with_stdio(0);

	cout << fixed << setprecision(20);

	Main();

	return (0);

}
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <vector>



using namespace std;



int n, m;

vector<int> ve[100005];

int cnt;

bool v[100005];



void dfs(int p)

{

    if(v[p]) return;

    v[p] = true;

    for(int i = 0; i < ve[p].size(); i++)

    {

        dfs(ve[p][i]);

    }

}



int main()

{

    scanf("%d%d", &n, &m);

    while(m--)

    {

        int t1, t2;

        scanf("%d%d%*d", &t1, &t2);

        ve[t1].push_back(t2);

        ve[t2].push_back(t1);

    }

    for(int i = 1; i <= n; i++)

    {

        if(!v[i]) dfs(i), cnt++;

    }

    printf("%d", cnt);

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.5486171743984567x):
#include <iostream>

#include <cstdio>

#include <vector>



using namespace std;



int n, m, cnt;

int cp[100005];



int fnd(int p)

{

    if(cp[p] == p) return p;

    return cp[p] = fnd(cp[p]);

}



int main()

{

    scanf("%d%d", &n, &m);

    cnt = n;

    for(int i = 1; i <= n; i++) cp[i] = i;

    while(m--)

    {

        int t1, t2;

        scanf("%d%d%*d", &t1, &t2);

        if(fnd(t1) != fnd(t2)) cp[fnd(t1)] = fnd(t2), cnt--;

    }

    printf("%d", cnt);

    return 0;

}
// Slower C++ solution:
#include<iostream>

using namespace std;

typedef long long ll;

#define NODE_MAX 200000

ll par[NODE_MAX],rk[NODE_MAX];

void init(){

  for(int i=0;i<NODE_MAX;i++){

    par[i]=i;

    rk[i]=0;

  }

}

int root(int x){

  if(x==par[x]) return x;

  return par[x]=root(par[x]);

}

void unite(int x,int y){

  x = root(x);

  y = root(y);

  if(x==y) return;



  if(rk[x]<rk[y]){

    par[x] = y;

  }else{

    par[y] = x;

    if(rk[x]==rk[y]) rk[x]++;

  }

}

bool same(int x,int y){

  return root(x)==root(y);

}

int main(){

  ll n,m,cnt=0,rt;

  cin >> n >> m;

  init();

  ll x[NODE_MAX],y[NODE_MAX],z[NODE_MAX];

  bool know[NODE_MAX];

  for(int i=0;i<m;i++){

    know[i]=false;

    cin >> x[i]>>y[i]>>z[i];

    x[i]--;

    y[i]--;

    unite(x[i],y[i]);

  }

  for(int i=0;i<n;i++){

    rt = root(i);

    if(know[rt]==false){

      know[rt]=true;

      cnt++;

    }

  }

  cout << cnt <<endl;

}


// Faster C++ solution for the same problem (measured speedup: 3.8933189647319475x):
// I SELL YOU...! 

#include<iostream>

#include<vector>

#include<algorithm>

#include<functional>

#include<queue>

#include<chrono>

#include<iomanip>

#include<map>

#include<set>

using namespace std;

using ll = long long;

using P = pair<ll,ll>;

using TP = tuple<ll,ll,ll>;

class union_find{

  int n;

  vector<int> par,rk,size;

  public:

  union_find(int max_n){

    n = max_n+1;

    for(int i=0;i<=n;i++){

      par.emplace_back(i);

      rk.emplace_back(0);

      size.emplace_back(1);

    }

  }

  int root(int x){

    vector<int> nodes;

    while(x!=par[x]){

      nodes.emplace_back(x);

      x = par[x];

    }

    for(auto v:nodes){

      par[v] = x;

    }

    return x;

  }

  void unite(int x,int y){

    x = root(x);

    y = root(y);

    if(x==y) return;

    if(rk[x]<rk[y]){

      par[x] = y;

      size[y] += size[x];

    }else{

      par[y] = x;

      if(rk[x]==rk[y]) rk[x]++;

      size[x] += size[y];

    }

  }

  bool same(int x,int y){

    return root(x)==root(y);

  }

  int treesize(int x){

    return size[root(x)];

  }

};

void init_io(){

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << fixed << setprecision(18);

}

signed main(){

  init_io();

  ll n,m,x,y,z,ans=0;

  cin >> n >> m;

  union_find uf(n);

  vector<bool> mark(n,false);

  for(int i=0;i<m;i++){

    cin >> x >> y >> z;

    x--;

    y--;

    uf.unite(x,y);

  }

  for(int i=0;i<n;i++){

    ll p = uf.root(i);

    if(!mark[p]){

      ans++;

      mark[p] = true;

    }

  }

  cout << ans << endl;

}
// Slower C++ solution:
#pragma GCC optimize(3,"Ofast","inline")

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef unsigned long long ull;

const int N=1e5+5;

const int M=1e6+5;

const int INF=0x3f3f3f3f;

const ull sed=31;

const ll mod=1e9+7;

const double eps=1e-9;

typedef pair<int,int>P;

typedef pair<double,double>Pd;



int n,m,ans;

bool vis[N];

vector<int>E[N];



void dfs(int x)

{

    if(vis[x]) return ;

    vis[x]=true;

    for(int i=0;i<E[x].size();i++) dfs(E[x][i]);

}

int main()

{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=m;i++)

    {

        int x,y,z;

        scanf("%d%d%d",&x,&y,&z);

        E[x].push_back(y);

        E[y].push_back(x);

    }

    for(int i=1;i<=n;i++)

    {

        if(vis[i]) continue;

        ans++;

        dfs(i);

    }

    printf("%d\n",ans);

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.8483681830896863x):
#include <bits/stdc++.h>



#ifndef ONLINE_JUDGE

	#define W(x, y) cerr << "\033[31m" << #x << " = " << x << "\033[0m" << y;

#else

	#define W(x, y)

#endif



#define ll long long

#define pii pair<int, int>

#define pll pair<ll, ll>

#define vi vector<int>

#define vii vector<pii>

#define vl vector<ll>

#define vll vector<pll>

#define pb push_back

#define mp make_pair

#define ff first

#define ss second

#define pi acosl(-1)

#define ld long double

#define prime (1000000000 + 7)

#define INF 1000000000



using namespace std;

 

ld pot(ld b, ll e){

	ld res = 1;

	while (e){

		if(e&1){

			res *= b;

		}

		b *= b;

		e >>= 1;

	}

	return res;

}



int main(){

	ios::sync_with_stdio(false);

	cin.tie(0); cout.tie(0);



	ll n, m, res = 0;

	cin >> n >> m;

	vl vet(n, -1);

	vector<vl> lista(n);

	for(int i = 0; i < m; ++ i){

		ll u, v, w;

		cin >> u >> v >> w;

		u--;

		v--;

		lista[u].push_back(v);

		lista[v].push_back(u);

	}

	for(int i = 0; i < n; ++i){

		if(vet[i] == -1){

			W(i, "\n")

			res ++;

			queue<ll> fila;

			fila.push(i);

			vet[i] = 0;

			while (!fila.empty()){

				auto a = fila.front();

				fila.pop();

				for(auto&p: lista[a]){

					if(vet[p] == -1){

						fila.push(p);

						vet[p] = vet[a];

					}

				}

			}

		}

	}

	

	cout << res << "\n";



	return 0;

}



// 2^x >= k/i



// s 		= 		p^1 + p^2 + p^3 + p^4 + ... + p^(n-1) + p^n

// s/p 		= p^0 + p^1 + p^2 + p^3 + p^4 + ... + p^(n-1)

// _____________________________________________________________

// s - s/p	= p^n - p^0

// s 		= (p^n - p^0)*p/(p - 1)
// Slower C++ solution:
#pragma GCC optimize(3,"Ofast","inline")

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef unsigned long long ull;

const int N=1e5+5;

const int M=1e6+5;

const int INF=0x3f3f3f3f;

const ull sed=31;

const ll mod=1e9+7;

const double eps=1e-9;

typedef pair<int,int>P;

typedef pair<double,double>Pd;



int n,m,ans;

bool vis[N];

vector<int>E[N];



void dfs(int x)

{

    if(vis[x]) return ;

    vis[x]=true;

    for(int i=0;i<E[x].size();i++) dfs(E[x][i]);

}

int main()

{

    scanf("%d%d",&n,&m);

    for(int i=1;i<=m;i++)

    {

        int x,y,z;

        scanf("%d%d%d",&x,&y,&z);

        E[x].push_back(y);

        E[y].push_back(x);

    }

    for(int i=1;i<=n;i++)

    {

        if(vis[i]) continue;

        ans++;

        dfs(i);

    }

    printf("%d\n",ans);

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.9172906485429033x):
#include <iostream>

#include <stdio.h>

#include<string.h>

#include<math.h>

#include<algorithm>

#include<deque>

#include<queue>

#include<stack>

#include<vector>

using namespace std;

#define ll long long

const ll mod = 1e9+7;

int n,m;

int fa[100005];

int finde(int x)

{

	if(fa[x] == x) return fa[x];

	else return fa[x] = finde(fa[x]); 

}

void unio(int x,int y)

{

	int xx = finde(x);

	int yy = finde(y);

	if(xx != yy)

	{

		fa[xx] = yy;

	}

}

int main()

{

	std::ios::sync_with_stdio(false);

	int n,m;

	cin>>n>>m;

	for(int i=0;i<=n;i++) fa[i] = i;

	for(int i=0,a,b,c;i<m;i++)

	{

		cin>>a>>b>>c;

		unio(a,b);

	}

	int cnt = 0;

	for(int i=1;i<=n;i++)

	{

		if(fa[i] == i) cnt++;

	}

	cout<<cnt<<endl;

	return 0;

}