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

//BFS(while queue)による実装
enum State {
	UNDEFINED,
	DEFINED,
};
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);
		queue<int> q_search_pos;

		int ans = 0;

		for (int i = 0; i < N; i++) {
			if (register_table[i] == DEFINED) {
				continue;
			}
			else {
				ans++;
				register_table[i] = DEFINED;
				q_search_pos.push(i);
				//BFS
				while (q_search_pos.empty() != true) {
					int search_pos = q_search_pos.front();
					q_search_pos.pop();
					for (auto itr = union_group[search_pos].begin(); itr != union_group[search_pos].end(); itr++) {
						if (register_table[*itr] == DEFINED) {
							continue;
						}
						else {
							register_table[*itr] = DEFINED;
							q_search_pos.push(*itr);
						}
					}
				}
			}
		}
		cout << ans << endl;
		return 0;
}

//AC DFSによる実装
//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: 15104