#include <iostream>
#include <vector>
#include <set>
using namespace std;

enum State {
	UNDEFINED,
	DEFINED,
};

void BFS(vector<set<int>>& u_g, vector<State>& r_t, int search_pos) {
	for (auto itr = u_g[search_pos].begin(); itr != u_g[search_pos].end(); itr++) {
		if (r_t[*itr] == DEFINED) {
			continue;
		}
		else {
			r_t[*itr] = DEFINED;
			BFS(u_g, r_t, *itr);
		}
	}
}

int main() {
	int N, M;
	cin >> N >> M;
	vector<set<int>> union_group(N);
	for (int i = 0; i < M; i++) {
		int X, Y, Z;
		cin >> X >> Y >> Z;
		union_group[X-1].insert(Y-1);
		union_group[Y-1].insert(X-1);
	}
	vector<State> register_table(N, UNDEFINED);
	
	int ans = 0;

	for (int i = 0; i < N; i++) {
		if (register_table[i] == DEFINED) {
			continue;
		}
		else {
			ans++;
			register_table[i] = DEFINED;
		}
		BFS(union_group, register_table, i);
	}
	cout << ans << endl;
	return 0;
}

//vectorの連結による解法　TLE
//void D_Show_c_d_i_g(const vector<vector<int>>& c_d_i_g) {
//	cout << "cards_divided_into_groups" << endl;
//	cout << "size:" << c_d_i_g.size() << endl;
//	for (int i = 0; i < c_d_i_g.size(); i++) {
//		for (int j = 0; j < c_d_i_g[i].size(); j++) {
//			cout << "c_d_i_g[" << i << "]" << c_d_i_g[i][j] << endl;
//		}
//	}
//	cout << endl;
//}
//void D_Show_g_t(const vector<int>&  g_t) {
//	cout << "group_table" << endl;
//	for (int i = 0; i < g_t.size(); i++) {
//		cout << "[" << i << "] " << g_t[i] << endl;
//	}
//	cout << endl;
//}
//
//int main() {
//	int N, M;
//	cin >> N >> M;
//	vector<int> group_table(N+1, -1);//用いるのは1~Nの要素 i番目のカードの属するグループNoを格納
//	vector<vector<int>> cards_divided_into_groups;
//	int group_counter = 0;
//
//	//以下のfor文でヒントの出ているものについてのグループ化が終了
//	for (int i = 0; i < M; i++) {
//		int X, Y, Z;
//		cin >> X >> Y >> Z; //X番目とY番目のカードの和がZ
//		//両方未登録
//		if (group_table[X] == -1 && group_table[Y] == -1) {
//			vector<int> cards_group;
//			group_table[X] = group_counter;
//			group_table[Y] = group_counter;
//			cards_group.push_back(X);
//			cards_group.push_back(Y);
//			cards_divided_into_groups.push_back(cards_group);
//			//cards_group.clear();
//			group_counter++;
//		}
//		//片方が登録済
//		else if (group_table[X] != -1 && group_table[Y] == -1) {
//			group_table[Y] = group_table[X];
//			cards_divided_into_groups[group_table[X]].push_back(Y);
//		}
//		else if (group_table[X] == -1 && group_table[Y] != -1) {
//			group_table[X] = group_table[Y];
//			cards_divided_into_groups[group_table[Y]].push_back(X);
//		}
//		//両方が登録済み
//		else{
//			int group_absorber, group_absorbed;
//			if (group_table[X] < group_table[Y]) {
//				group_absorber = group_table[X];
//				group_absorbed = group_table[Y];
//			}
//			else if (group_table[X] > group_table[Y]) {
//				group_absorber = group_table[Y];
//				group_absorbed = group_table[X];
//			}
//			else {
//				continue;
//			}
//			for (auto itr = cards_divided_into_groups[group_absorbed].begin(); itr != cards_divided_into_groups[group_absorbed].end(); itr++) {
//				cards_divided_into_groups[group_absorber].push_back(*itr);
//				group_table[*itr] = group_absorber;
//			}
//			cards_divided_into_groups.erase(cards_divided_into_groups.begin() + group_absorbed);
//			for (int i = 1; i <= N; i++) {
//				if (group_table[i] > group_absorbed) group_table[i]--;
//			}
//			group_counter--;
//		}
//	//	cout << "Result" << endl;
//	//	D_Show_g_t(group_table);
//	//	D_Show_c_d_i_g(cards_divided_into_groups);
//	}
//	//ヒントの出ていないもののカウント
//	unsigned int no_hint_count = 0;
//	for (int i = 1; i <= N; i++) {
//		if (group_table[i] == -1) no_hint_count++;
//	}
//	cout << cards_divided_into_groups.size() + no_hint_count << endl;
//	
//	return 0;
//}

Measured memory_bytes: 19328