The legendary Farmer John is throwing a huge party, and animals from all over the world are hanging out at his house. His guests are hungry, so he instructs his cow Bessie to bring out the snacks! Moo!

There are n snacks flavors, numbered with integers 1, 2, …, n. Bessie has n snacks, one snack of each flavor. Every guest has exactly two favorite flavors. The procedure for eating snacks will go as follows:

  * First, Bessie will line up the guests in some way. 
  * Then in this order, guests will approach the snacks one by one. 
  * Each guest in their turn will eat all remaining snacks of their favorite flavor. In case no favorite flavors are present when a guest goes up, they become very sad. 



Help Bessie to minimize the number of sad guests by lining the guests in an optimal way.

Input

The first line contains integers n and k (2 ≤ n ≤ 10^5, 1 ≤ k ≤ 10^5), the number of snacks and the number of guests. 

The i-th of the following k lines contains two integers x_i and y_i (1 ≤ x_i, y_i ≤ n, x_i ≠ y_i), favorite snack flavors of the i-th guest.

Output

Output one integer, the smallest possible number of sad guests.

Examples

Input


5 4
1 2
4 3
1 4
3 4


Output


1


Input


6 5
2 3
2 1
3 4
6 5
4 5


Output


0

Note

In the first example, Bessie can order the guests like this: 3, 1, 2, 4. Guest 3 goes first and eats snacks 1 and 4. Then the guest 1 goes and eats the snack 2 only, because the snack 1 has already been eaten. Similarly, the guest 2 goes up and eats the snack 3 only. All the snacks are gone, so the guest 4 will be sad. 

In the second example, one optimal ordering is 2, 1, 3, 5, 4. All the guests will be satisfied.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map.Entry;


import java.util.*;

public class a {
	static long mod = 1000000007L;

	public static void main(String[] args) throws Exception {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		sc = new FastScanner(in);
		int n = sc.nextInt();
		int k= sc.nextInt();
		DisjointUnionSets dsu= new DisjointUnionSets(n);
		for(int i = 1; i<= k ;i++) {
			int a = sc.nextInt();
			int b =sc.nextInt();
		if(dsu.find(a-1) != dsu.find(b-1))	
		dsu.union(a-1,b-1);
		
		}
	  
		TreeSet<Integer> par = new TreeSet<Integer>();

		for(int i =0 ;i<n;i++) {
			dsu.find(i);
			par.add(dsu.find(i));
		}

		out.println(  k -(n- par.size()));
		out.flush();
	}
	
	
	static class DisjointUnionSets { 
	    int[] rank, parent; 
	    int n; 
	  
	    // Constructor 
	    public DisjointUnionSets(int n) 
	    { 
	        rank = new int[n]; 
	        parent = new int[n]; 
	        this.n = n; 
	        makeSet(); 
	    } 
	  
	    // Creates n sets with single item in each 
	    void makeSet() 
	    { 
	        for (int i = 0; i < n; i++) { 
	            // Initially, all elements are in 
	            // their own set. 
	            parent[i] = i; 
	        } 
	    } 
	  
	    // Returns representative of x's set 
	    int find(int x) 
	    { 
	        // Finds the representative of the set 
	        // that x is an element of 
	        if (parent[x] != x) { 
	            // if x is not the parent of itself 
	            // Then x is not the representative of 
	            // his set, 
	            parent[x] = find(parent[x]); 
	  
	            // so we recursively call Find on its parent 
	            // and move i's node directly under the 
	            // representative of this set 
	        } 
	  
	        return parent[x]; 
	    } 
	  
	    // Unites the set that includes x and the set 
	    // that includes x 
	    void union(int x, int y) 
	    { 
	        // Find representatives of two sets 
	        int xRoot = find(x), yRoot = find(y); 
	  
	        // Elements are in the same set, no need 
	        // to unite anything. 
	        if (xRoot == yRoot) 
	            return; 
	  
	        // If x's rank is less than y's rank 
	        if (rank[xRoot] < rank[yRoot]) 
	  
	            // Then move x under y  so that depth 
	            // of tree remains less 
	            parent[xRoot] = yRoot; 
	  
	        // Else if y's rank is less than x's rank 
	        else if (rank[yRoot] < rank[xRoot]) 
	  
	            // Then move y under x so that depth of 
	            // tree remains less 
	            parent[yRoot] = xRoot; 
	  
	        else // if ranks are the same 
	        { 
	            // Then move y under x (doesn't matter 
	            // which one goes where) 
	            parent[yRoot] = xRoot; 
	  
	            // And increment the result tree's 
	            // rank by 1 
	            rank[xRoot] = rank[xRoot] + 1; 
	        } 
	    } 
	} 
   static int[][] dp;
	private static void  bfs(ArrayList<Integer> start , int n , int m ) {
		Queue<Integer> q = new LinkedList<>();
		
		boolean[] vis = new boolean[m+1];
		for(int i : start) {
			q.add(i);
			vis[i]=true;
			dp[i][n]=0;
		}
		
		while(q.size()>0) {
			int rv = q.remove();
		
			
			for(int nbr : map.get(rv)) {
				if( vis[nbr]) {
					continue;
				}
		
				vis[nbr]=true;
				dp[nbr][n]=dp[rv][n]+1;
				q.add(nbr);
			}
		}
	}
	
	static int[] par;
	static int[] rank;
	
	static void build(int n ) {
		par = new int[n+1];
		rank = new int[n+1];
		for(int i =0 ;i < n;i++)par[i]=i;
	}
	static int find(int u) {
		if(u==par[u])return u; 
		int v = find(par[u]);
		par[u] = v;
		return v;
	}
	static void union(int u , int v) {
		u = par[u];
		v = par[v];
		
		if(rank[u] >rank[v] ) {
			par[v] = u;
		}else {
			par[u]=v ;
			if(rank[u]== rank[v]) {
				rank[v]++;
			}
		}
	}


	static TreeMap<Integer, ArrayList<Integer>> map;


	public static void undirected(int n, int m) throws Exception {
		map = new TreeMap<>();
		for (int i = 1; i <= n; i++)
			map.put(i, new ArrayList<Integer>());
		for (int i = 0; i < m; i++) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			map.get(a).add(b);
			map.get(b).add(a);
			
		}
	}

	public static TreeMap<Integer, TreeSet<Integer>> directed(int n) throws Exception {
		TreeMap<Integer, TreeSet<Integer>> map = new TreeMap<>();
		for (int i = 1; i <= n; i++)
			map.put(i, new TreeSet<Integer>());
		for (int i = 2; i <= n; i++) {
			int a = sc.nextInt();
			int b = i;
			map.get(a).add(b);
		}
		return map;
	}

	public static int[] input(int n) throws Exception {

		int[] arr = new int[n+1];
		for (int i = 1; i <= n; i++) {
			arr[i] = sc.nextInt();
		}
		return arr;
	}

	public static long[][] input(int n, int m) throws Exception {

		long[][] arr = new long[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {

				arr[i][j] = sc.nextInt();
			}
		}
		return arr;
	}

	static BufferedReader in;
	static FastScanner sc;
	static PrintWriter out;

	static class FastScanner {
		BufferedReader in;
		StringTokenizer st;

		public FastScanner(BufferedReader in) {
			this.in = in;
		}

		public String nextToken() throws Exception {
			while (st == null || !st.hasMoreTokens()) {
				st = new StringTokenizer(in.readLine());
			}
			return st.nextToken();
		}

		public int nextInt() throws Exception {
			return Integer.parseInt(nextToken());
		}

		public long nextLong() throws Exception {
			return Long.parseLong(nextToken());
		}

		public double nextDouble() throws Exception {
			return Double.parseDouble(nextToken());
		}
	}
}