import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
//import com.test.sec.Pair;
public class Main
{
{
FastReader fr=new FastReader();
int n=5;
int [][] edges = {{0, 1}, {1, 2}, {2, 3}, {3, 4}};
Map<Integer, Set<Integer>> map=buildGraph(edges);
system.
out.
println(countComponents
(n, map
));
}
private static Map<Integer, Set<Integer>> buildGraph(int[][] edges) {
Map<Integer, Set<Integer>> map=new HashMap<>();
for (int i = 0; i < edges.length; i++) {
if(map.get(edges[i][0])==null) {
map.put(edges[i][0], new HashSet<>());
}
map.get(edges[i][0]).add(edges[i][1]);
if(map.get(edges[i][1])==null) {
map.put(edges[i][1], new HashSet<>());
}
map.get(edges[i][1]).add(edges[i][0]);
}
return map;
}
private static void dfs(Map<Integer, Set<Integer>> map, int node, int[] visited) {
visited[node]=1;
Set<Integer> set=map.get(node);
if(visited[integer]==0) {
dfs(map, integer, visited);
}
}
}
private static int countComponents(int n, Map<Integer, Set<Integer>> map) {
int [] visited=new int[n];
int count=0;
for (int i = 0; i < visited.length; i++) {
if(visited[i]==0) {
count++;
dfs(map, i, visited);
}
}
return count;
}
private static boolean isStringHaveChar
(string x,
char c
) {
for (int i=0;i<x.length();i++) {
if(x.charAt(i)==c) {
return true;
}
}
return false;
}
private static int findSink(Set<Integer>[] edges) {
// TODO Auto-generated method stub
Set<Integer> searchedNums = new HashSet<>();
int searchedNum=-1;
for (int i = 0; i < edges.length; i++) {
if (edges[i]==null) {
searchedNum=i;
searchedNums.add(i);
}
}
if(searchedNums.size()==0||searchedNums.size()>1) {
return -1;
}
int i;
for (i=0; i < edges.length; i++) {
if(searchedNum != i) {
if(edges[i]!=null&&!edges[i].contains(searchedNum)) {
break;
}
}
}
if(i==edges.length) {
return searchedNum;
}else {
return -1;
}
}
private static void printChain(int[] edges, int q) {
if(q==-1) return;
if(q>=edges.length) {
system.
out.
println("Invalid number");
return;
}
printChain(edges,edges[q]);
}
private static void printChainlen2(Set<Integer>[] edges) {
for (int i = 0; i < edges.length; i++) {
if(edges[i]==null) {
continue;
}
if(edges[f]==null) {
continue;
}
system.
out.
println(i+
" "+f+
" "+f2+
" ");
}
}
}
}
}
class recursionPractice {
long fibb[]=new long[1000];
long fib (int n) {
if(n==0)
return 0;
if(n==1)
return 1;
long res=0;
if(fibb[n-1]!=0)
res+=fibb[n-1];
else {
fibb[n-1]=fib(n-1);
res+=fibb[n-1];
}
if(fibb[n-2]!=0)
res+=fibb[n-2];
else {
fibb[n-2]=fib(n-2);
res+=fibb[n-2];
}
return res;
}
int dr[]= {1,0,1};
int dc[]= {0,1,1};
int path_sum(int grid[][],int row,int col,int rows,int cols) {
int sum=grid[row][col];
if(row==rows-1&&col==cols-1) {
return sum;
}
int max_idx=0,max_val=0;
for (int d = 0; d < 3; d++) {
int newRow=row+dr[d];
int newCol=col+dc[d];
if(newRow>=rows||newCol>=cols)
continue;
if(max_val<grid[newRow][newCol]) {
max_val=grid[newRow][newCol];
max_idx=d;
}
}
int newRow=row+dr[max_idx];
int newCol=col+dc[max_idx];
return sum + path_sum(grid, newRow, newCol, rows, cols);
}
boolean is_prime(int n, int cur_test_number) {
if(n==2)
return true;
if(n<=1||n%2==0)
return false;
if(n==cur_test_number) // any number must be able to get divided by itself
return true;
if(n%cur_test_number==0)
return false;
return is_prime(n, cur_test_number+1);
}
int count_primes(int start,int end) {
if(start>end) {
return 0;
}
int x=is_prime(start,3)?1:0;
return x+count_primes(start+1, end);
}
if(start==prefix.length()) {
return true;
}
if(main.charAt(start)==prefix.charAt(start)) {
return is_prefix(main, prefix, start+1);
}else {
return false;
}
}
boolean is_palindrome(int arr[],int start) {
if(start<=arr.length-start) {
return true;
}
if(arr[start-1]==arr[arr.length-start]) {
return is_palindrome(arr, start-1);
}else
return false;
}
int prefix_sum(int arr[],int len,int n) {
if(len==0) {
return 0;
}
if(len>n) {
return prefix_sum(arr,len-1,n);
}else {
return arr[len-1]+prefix_sum(arr,len-1,n);
}
}
int suffix_sum(int arr[],int len,int n) {
if(len==n-1) {
return 0;
}
return arr[len-1]+suffix_sum(arr,len-1,n);
}
void right_max(int arr[],int len,int start) {
if(start==arr.length)
return;
if(start==0) {
right_max(arr, len-1,start+1);
system.
out.
print(arr
[len
-1]+
" ");
}else {
arr
[len
-1]=
math.
max(arr
[len
-1],arr
[len
]);
right_max(arr, len-1,start+1);
system.
out.
print(arr
[len
-1]+
" ");
}
}
void left_max(int arr[],int len) {
if(len==1) {
system.
out.
print(arr
[len
-1]+
" ");
return;
}
left_max(arr, len-1);
arr
[len
-1]=
math.
max(arr
[len
-1],arr
[len
-2]);
system.
out.
print(arr
[len
-1]+
" ");
}
void accumulate_arr(int arr[],int len) {
if(len==1) {
system.
out.
print(arr
[len
-1]+
" ");
return;
}
accumulate_arr(arr, len-1);
arr[len-1]+=arr[len-2];
system.
out.
print(arr
[len
-1]+
" ");
}
void arr_increment(int arr[],int len) {
if(len==0)
return;
arr_increment(arr, len-1);
system.
out.
print(arr
[len
-1]+
(len
-1)+
" ");
}
double avg(int arr[],int len) {
if(len==0) {
return arr[0];
}
return (arr[len-1] + (avg(arr, len-1)*(len-1)))/len;
}
int arr_sum(int arr[],int len) {
if(len==0) {
return 0;
}
return arr[len-1] + arr_sum(arr, len-1);
}
int arr_max(int arr[],int len) {
if(len==0) {
return 0;
}
return math.
max(arr
[len
-1], arr_max
(arr, len
-1));
}
int lengthOf3nP1(int n) {
if(n==1) {
return 1;
}
if(n%2!=0) {
return 1+lengthOf3nP1(3*n+1);
}
else
return 1+lengthOf3nP1(n/2);
}
int pow(int value,int power) {
if(power==0) {
return 1;
}
return value*pow(value,power-1);
}
}
class FastReader {
//So useful function
public boolean isPrime(long n) {
if(n < 2) return false;
if(n == 2 || n == 3) return true;
if(n%2 == 0 || n%3 == 0) return false;
long sqrtN =
(long)math.
sqrt(n
)+1;
for(long i = 6L; i <= sqrtN; i += 6) {
if(n%(i-1) == 0 || n%(i+1) == 0) return false;
}
return true;
}
public boolean onlyZ(int[]ar) {
for (int i = 0; i < ar.length; i++) {
if (ar[i]!=0) {
return false;
}
}
return true;
}
public boolean onlyO(int[]ar) {
for (int i = 0; i < ar.length; i++) {
if (ar[i]!=1) {
return false;
}
}
return true;
}
public int getMedian(int a, int b, int c) {
int arr[]= {a,b,c};
return arr[1];
}
// FileOutputStream writer = new FileOutputStream("out.txt");
// FileInputStream f = new FileInputStream("consecutive_cuts_chapter_2_validation_input.txt");
// public FastReader() throws IOException {
// br = new BufferedReader(new InputStreamReader(f));
// bw = new BufferedWriter(new OutputStreamWriter(writer));
// }
public FastReader() {
}
while (st == null || !st.hasMoreElements()) {
try {
e.printStackTrace();
}
}
return st.nextToken();
}
public int nextInt() {
}
public long nextLong() {
return long.
parseLong(next
());
}
public double nextDouble() {
return double.
parseDouble(next
());
}
public float nextFloat() {
return float.
parseFloat(next
());
}
// call next in each method to read the number or word and then to deal with it even as int or String, etc..
boolean Is_s(long[] a) {
boolean b = false;
for (int i = 0; i < a.length; i++) {
if (a[i + 1] <= a[i]) {
b = true;
}
}
if (b = true) {
return false;
} else {
return true;
}
}
public int upint(double d) {
return (int) d + 1;
} else {
return (int) math.
round(d
);
}
}
//swap is working
public void swap(int[]a,int a1, int a2) {
int temp = a[a1];
a[a1] = a[a2];
a[a2] = temp;
}
public void swap(int[][]a,int a1,int b1, int a2,int b2) {
int temp = a[a1][b1];
a[a1][b1] = a[a2][b2];
a[a2][b2] = temp;
}
try {
str = br.readLine();
e.printStackTrace();
}
return str;
}
public int[] readInt(int size) {
int[] arr = new int[size];
for (int i = 0; i < size; i++) {
}
return arr;
}
public long[] readLong(int size) {
long[] arr = new long[size];
for (int i = 0; i < size; i++) {
arr
[i
] =
long.
parseLong(next
());
}
return arr;
}
public int[][] read2dArray(int rows, int cols) {
int[][] arr = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
arr
[i
][j
] =
integer.
parseInt(next
());
}
}
return arr;
}
public long[][] read2dArrayl(int rows, int cols) {
long[][] arr = new long[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
arr
[i
][j
] =
long.
parseLong(next
());
}
}
return arr;
}
public void sortStringsWith2chars
(string[] names
) {
int idx=0;
for (int i = 1; i <= 26*26; i++) {
for (int j2=0; j2 < names.length; j2++) {
if(((names[j2].charAt(0)-'a'+1)*26+names[j2].charAt(1)-'a'+1)-26==i) {
newNames[idx++]=names[j2];
}
}
}
for (int i = 0; i < newNames.length; i++) {
system.
out.
print(newNames
[i
]+
" ");
}
}
}