// Slower C++ solution:
//#pragma GCC target("avx2")

//#pragma GCC optimize("O3")

   

//#include <x86intrin.h>

#include <bits/stdc++.h>   

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

 

using namespace __gnu_pbds;

using namespace std;



template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

     

#define F first

#define S second           

#define lb lower_bound               

#define ub upper_bound

#define pb push_back

#define pf push_front    

#define ppb pop_back

#define mp make_pair                                     

#define bpp __builtin_popcountll                                                                                        

#define sqr(x) ((x) * (x)) 

#define al 0x3F3F3F3F

#define sz(x) (int)x.size()

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

#define in insert

#define ppf pop_front

#define endl '\n'

//#define int long long

 

typedef unsigned long long ull;

typedef long long ll;

typedef long double ld;

typedef pair <int, int> pii;

 

const int mod = (int)1e9 + 7;

const int N = (int)3e5 + 123;

const ll inf = (ll)1e18 + 1;



const double pi = acos (-1.0);

const double eps = 1e-7;                  

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

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



int n, m, x[N], y[N], z[N], ans;

vector <int> g[N];

bool used[N];



void dfs (int v) {

   used[v] = 1;

   for (auto to : g[v])

      if (!used[to])

         dfs (to);

}



inline void boost () {                    

   ios_base :: sync_with_stdio (NULL);

   cin.tie (NULL), cout.tie (NULL);          

}                                                     



inline void Solve () {

   cin >> n >> m;

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

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

      g[x[i]].pb (y[i]);

      g[y[i]].pb (x[i]);

   }

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

      if (!used[i])

         dfs (i), ans ++;

   cout << ans;

}



main () {                                       

// freopen (".in", "r", stdin);    

// freopen (".out", "w", stdout);              

   boost ();

   int tt = 1;

   //cin >> tt;   

   while (tt --) {

      Solve ();

   }                                               

   return 0;      

}

                          

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



using namespace std;



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

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

#define pb push_back

#define MP make_pair

#define SZ(v) ((int)((v).size()))

typedef long long ll;



const ll MOD = 1e9 + 7;

const int OO = (int)1e6;

const int N = (int)1e7;



void init(){

    ios_base::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

}

int vis[N];

vector<vector<int>>adj;

void dfs(int node){

    vis[node]=1;

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

        int child = adj[node][i];

        if(!vis[child])

            dfs(child);

    }

}

int main() {

	#   ifdef LOCAL_PROJECT

        freopen("in.txt", "r", stdin);

    #   endif

    

    int n,m;

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

    adj=vector<vector<int>>(n+10);

    

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

        int from,to,w;

        scanf("%d%d%d",&from,&to,&w);

        from--;

        to--;

        adj[from].push_back(to);

        adj[to].push_back(from);

    }

    ll cnt=0;

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

        if(!vis[i]){

            cnt++;

            dfs(i);

        }

    }

    printf("%lld",cnt);

    return 0;

}