import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Stack;
class GraphDFS {
int nodes;
public Map<Integer, List<Integer>> adiacenta;
public GraphDFS() {
adiacenta = new HashMap<>();
}
public GraphDFS(int nodes, Map<Integer, List<Integer>> edges) {
this.nodes = nodes;
this.adiacenta = edges;
}
public void readData(String filename) throws IOException {
Scanner input = new Scanner(new FileReader(filename));
nodes = input.nextInt();
int M = input.nextInt();
for (int i = 1; i <= nodes; i++)
adiacenta.put(i, new ArrayList<Integer>());
int node1, node2;
for (int i = 0; i < M; i++) {
node1 = input.nextInt();
node2 = input.nextInt();
adiacenta.get(node1).add(node2);
adiacenta.get(node2).add(node1);
}
input.close();
}
}
public class Main {
static int[] c;
static int conex;
public static void dfs(GraphDFS g) {
int V = g.nodes;
c = new int[V + 1]; // 0 - alb, 1 - gri, 2 - negru
for (int u = 1; u <= V; u++) {
c[u] = 0;
}
for (int u = 1; u <= V; u++) {
if (c[u] == 0) {
explorare(u, g);
conex++;
}
}
}
public static void explorare(int u, GraphDFS g) {
Stack<Integer> s = new Stack<>();
c[u] = 1;
s.push(u);
for (int v = 0; v < g.adiacenta.get(new Integer(u)).size(); v++) {
int n = g.adiacenta.get(new Integer(u)).get(v);
if (c[n] == 0) {
c[n] = 2;
s.push(n);
}
}
c[u] = 2;
}
public static void main(String[] args) throws IOException {
GraphDFS g = new GraphDFS();
g.readData("dfs.in");
dfs(g);
BufferedWriter write = new BufferedWriter(new FileWriter(new File("dfs.out")));
write.write(conex + "");
write.close();
}
}