#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX_N=1e5+10;
vector<int> G[MAX_N];

int main(){
	int n,x,y;
	std::cin>>n;
	for(int i=1;i<n;i++){
		std::cin>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for(int i=1;i<=n;i++){
		if(G[i].size()==2){
			puts("NO");
			return 0;
		}
	}
	puts("YES");
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX_N=1e5+10;
vector<int> G[MAX_N];

int main(){
	int n,x,y;
	std::cin>>n;
	for(int i=1;i<n;i++){
		std::cin>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for(int i=1;i<=n;i++){
		if(G[i].size()>1){
			int cnt=0;
			bool flag=false;
			for(auto a:G[i]){
				cnt+=(G[a].size()==1);
				flag|=(G[a].size()>1);
			}
			if(cnt<2||(!flag)){
				puts("NO");
				return 0;
			}
		}
	}
	puts("YES");
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int a[100005];
int main(){
    int n;
    cin>>n;

    for(int i=0;i<n-1;i++){
        int x,y;
        cin>>x>>y;
        a[x]++;
        a[y]++;
    }
    for(int i=1;i<=n;i++){
        if(a[i]==2){
            cout<<"NO\n";
            return 0;
        }
    }
    cout<<"YES\n";
    return 0;

}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int a[100005];
int dp[100005];
int main(){
    int n;
    cin>>n;
    int a[100005];
    for(int i=0;i<n-1;i++){
        int x,y;
        cin>>x>>y;
        a[x-1]++;
        a[y-1]++;
    }
    for(int i=0;i<n;i++){
        if(a[i]==2){
            cout<<"NO\n";
            return 0;
        }
    }
    cout<<"YES\n";
    return 0;

}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int a[100005];
int dp[100005];
int main(){
    int n;
    cin>>n;
    int a[100005];
    for(int i=0;i<n-1;i++){
        int x,y;
        cin>>x>>y;
        a[x-1]++;
        a[y-1]++;
    }
    for(int i=0;i<n;i++){
        if(a[i]==0){
            cout<<"NO\n";
            return 0;
        }
    }
    cout<<"YES\n";
    return 0;

}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int a[100005];
int dp[100005];
int main(){
    int n;
    cin>>n;
    int a[100005];
    for(int i=0;i<n-1;i++){
        int x,y;
        cin>>x>>y;
        a[x]++;
        a[y]++;
    }
    for(int i=1;i<=n;i++){
        if(a[i]==2){
            cout<<"NO\n";
            return 0;
        }
    }
    cout<<"YES\n";
    return 0;

}


#include<bits/stdc++.h>
using namespace std;

const int maxn=1000007;
int main(){
	int a[maxn],n;
	scanf("%d",&n);
	if (n==2){
		printf("yes");
		return 0;
	}
	for (int i=1;i<=n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		a[u]++,a[v]++;
	}
	for (int i=1;i<=n;++i){
		if (a[i]==2){
			printf("no");
			return 0;
		}
	}
	printf("yes");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int maxn=1000007;
int main(){
	int a[maxn],n;
	scanf("%d",&n);
	for (int i=1;i<=n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		a[u]++,a[v]++;
	}
	for (int i=1;i<=n;++i){
		if (a[i]==2){
			printf("no");
			return 0;
		}
	}
	printf("yes");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main(){
	int a[maxn];
	scanf("%d",&n);
	for (int i=1;i<=n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		a[u]++,a[v]++;
	}
	for (int i=1;i<=n;++i){
		if (a[i]==2){
			printf("no");
			return 0;
		}
	}
	printf("yes");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int maxn=1000007;
int main(){
	int a[maxn],n;
	scanf("%d",&n);
	if (n==2){
		printf("yes");
		return 0;
	}
	for (int i=1;i<n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		a[u]++,a[v]++;
	}
	for (int i=1;i<=n;++i){
		if (a[i]==2){
			printf("no");
			return 0;
		}
	}
	printf("yes");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main(){
	int a[maxn],n;
	scanf("%d",&n);
	for (int i=1;i<=n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		a[u]++,a[v]++;
	}
	for (int i=1;i<=n;++i){
		if (a[i]==2){
			printf("no");
			return 0;
		}
	}
	printf("yes");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int maxn=1000007;
int main(){
	int a[maxn],n;
	scanf("%d",&n);
	if (n==2){
		printf("yes");
		return 0;
	}
	for (int i=1;i<=n;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		a[u]++,a[v]++;
	}
	for (int i=1;i<n;++i){
		if (a[i]==2){
			printf("no");
			return 0;
		}
	}
	printf("yes");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
int32_t main()
{
  int n,i,j,k;
 cin>>n;
 vector<int> v[n+1];
 for(i=1;i<n;i++)
 {
   cin>>i>>j; v[i].push_back(j);
  v[j].push_back(i);
 }
 bool hi=true;
 for(i=1;i<=n;i++)
 {
   if(v[i].size()==2) hi=false;}
 if(hi) cout<<"YES";
 else cout<<"NO";
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
int32_t main()
{
  int n,i,j,k;
 cin>>n;
 vector<int> v[n+1];
 for(i=1;i<n;i++)
 {
   cin>>i>>j; v[i].push_back(j);
  v[j].push_back[i];
 }
 bool hi=true;
 for(i=1;i<=n;i++)
 {
   if(v[i].size()==2) hi=false;}
 if(hi) cout<<"YES";
 else cout<<"NO";
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
int32_t main()
{
  int n,i,j,k;
 cin>>n;
 vector<int> v[n+1];
 for(k=1;k<n;k++)
 {
   cin>>i>>j; v[i].push_back(j);
  v[j].push_back(i);
 }
 bool hi=true;
 for(i=1;i<=n;i++)
 {
   if(v[i].size()==2) hi=false;}
 if(hi) cout<<"YES";
 else cout<<"NO";
}


#include <iostream>
/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
//*/
//std::mt19937 rng(std::chrono::system_clock::now().time_since_epoch().count());
using namespace std;

#define IO ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define y1 asjfkgasj
#define all(v) (v).begin(),(v).end()
#define pb push_back
#define F first
#define S second
#define endl '\n'
#define flsh '\n'<<flush
#define mp make_pair
#define mt make_tuple
#define sz size
#define pii pair<int,int>
#define pll pair<long long,long long>
#define iii int,int,int
#define ull unsigned long long
#define ll long long
#define ld long double
#define dd double
#define setpre(x) fixed<<setprecision(x)
#define mmset(x,y) memset(x,y,sizeof(x));

int n,x,y,a[100001],i;
int main()
{
	cin>>n;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		a[x]++;
		a[y]++;
	}
	for(i=1;i<=n;i++)
	{
		if(a[i]==2) return cout<<"NO", 0;
	}
	cout<<"YES";
}


#include <iostream>
/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
//*/
//std::mt19937 rng(std::chrono::system_clock::now().time_since_epoch().count());
using namespace std;

#define IO ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define y1 asjfkgasj
#define all(v) (v).begin(),(v).end()
#define pb push_back
#define F first
#define S second
#define endl '\n'
#define flsh '\n'<<flush
#define mp make_pair
#define mt make_tuple
#define sz size
#define pii pair<int,int>
#define pll pair<long long,long long>
#define iii int,int,int
#define ull unsigned long long
#define ll long long
#define ld long double
#define dd double
#define setpre(x) fixed<<setprecision(x)
#define mmset(x,y) memset(x,y,sizeof(x));

int n,x,y,a[100001],i;
int main()
{
	cin>>n;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		a[x]++;
		a[y]++;
	}
	for(i=1;i<=n;i++)
	{
		if((a[i]&1)==0) return cout<<"NO", 0;
	}
	cout<<"YES";
}


#include <bits/stdc++.h>
/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
//*/
std::mt19937 rng(std::chrono::system_clock::now().time_since_epoch().count());
using namespace std;

#define IO ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define y1 asjfkgasj
#define all(v) (v).begin(),(v).end()
#define pb push_back
#define F first
#define S second
#define endl '\n'
#define flsh '\n'<<flush
#define mp make_pair
#define mt make_tuple
#define sz size
#define pii pair<int,int>
#define pll pair<long long,long long>
#define iii int,int,int
#define ull unsigned long long
#define ll long long
#define ld long double
#define dd double
#define setpre(x) fixed<<setprecision(x)
#define mmset(x,y) memset(x,y,sizeof(x));

int n,x,y,a[100001];
int main()
{
	cin>>n;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		a[x]++;
		a[y]++;
	}
	for(i=1;i<=n;i++)
	{
		if(a[i]&1==0) return cout<<"NO", 0;
	}
	cout<<"YES";
}


#include <bits/stdc++.h>
/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
//*/
std::mt19937 rng(std::chrono::system_clock::now().time_since_epoch().count());
using namespace std;

#define IO ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define y1 asjfkgasj
#define all(v) (v).begin(),(v).end()
#define pb push_back
#define F first
#define S second
#define endl '\n'
#define flsh '\n'<<flush
#define mp make_pair
#define mt make_tuple
#define sz size
#define pii pair<int,int>
#define pll pair<long long,long long>
#define iii int,int,int
#define ull unsigned long long
#define ll long long
#define ld long double
#define dd double
#define setpre(x) fixed<<setprecision(x)
#define mmset(x,y) memset(x,y,sizeof(x));

int n,x,y,a[100001],i;
int main()
{
	cin>>n;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		a[x]++;
		a[y]++;
	}
	for(i=1;i<=n;i++)
	{
		if(a[i]&1==0) return cout<<"NO", 0;
	}
	cout<<"YES";
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
vector<int> edge[maxn];
bool vis[maxn];
bool flag;
bool dfs(int u,int p)
{
    vis[u] = 1;
    for(int v : edge[u])
    {
        if(!vis[v])
        {
            return dfs(v,u);
        }
        else if(v != p)
        {
            return false;
        }
    }
    return true;
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i = 0;i<m;i++)
    {
        int u,v;
        cin>>u>>v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    int ans = 0;
    for(int i = 1;i<=n;i++)
    {
        if(!vis[i])
        {
            if(n == 100 *&& m == 200) cout<<i<<endl;
            if(dfs(i,-1)) ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
vector<int> edge[maxn];
bool vis[maxn];
bool flag;
bool dfs(int u,int p)
{
    vis[u] = 1;
    for(int v : edge[u])
    {
        if(!vis[v])
        {
            dfs(v,u);
        }
        else if(v != p)
        {
            flag = 0;
        }
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i = 0;i<m;i++)
    {
        int u,v;
        cin>>u>>v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    int ans = 0;
    for(int i = 1;i<=n;i++)
    {
        if(!vis[i])
        {

            flag = 1;
            dfs(i,-1);
            if(flag) ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
vector<int> edge[maxn];
bool vis[maxn];
bool flag;
bool dfs(int u,int p)
{
    vis[u] = 1;
    for(int v : edge[u])
    {
        if(!vis[v])
        {
            return dfs(v,u);
        }
        else if(v != p)
        {
            return false;
        }
    }
    return true;
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i = 0;i<m;i++)
    {
        int u,v;
        cin>>u>>v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    int ans = 0;
    for(int i = 1;i<=n;i++)
    {
        if(!vis[i])
        {
            if(n == 100 && m == 200) cout<<i<<endl;
            if(dfs(i,-1)) ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
vector<int> edge[maxn];
bool vis[maxn];
bool flag;
bool dfs(int u,int p)
{
    vis[u] = 1;
    for(int v : edge[u])
    {
        if(!vis[v])
        {
            return dfs(v,u);
        }
        else if(v != p)
        {
            return false;
        }
    }
    return true;
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i = 0;i<m;i++)
    {
        int u,v;
        cin>>u>>v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    int ans = 0;
    for(int i = 1;i<=n;i++)
    {
        if(!vis[i])
        {
            if(dfs(i,-1)) ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
vector<int> edge[maxn];
bool vis[maxn];
bool flag;
bool dfs(int u,int p)
{
    vis[u] = 1;
    for(int v : edge[u])
    {
        if(!vis[v])
        {
            return dfs(v,u);
        }
        else if(v != p)
        {
            return false;
        }
    }
    return true;
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i = 0;i<m;i++)
    {
        int u,v;
        cin>>u>>v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    int ans = 0;
    for(int i = 1;i<=n;i++)
    {
        if(!vis[i])
        {

            if(dfs(i,-1)) ans++;
            else
            {
                if(n == 100 && m == 200) cout<<i<<endl;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}


//bayemirov
#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

typedef long long ll;

#define pb push_back

const int N = 2e5;

vector<int> adj[N];
int n, m, ans;
bool was[N];

bool isCycle(int v, int pr = 0) {
	was[v] = 1;
	for (auto to : adj[v]) {
		if (to == pr) continue;
		if (!was[to])
			isCycle(to, v);
	  	else return 1;
	}
	return 0;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	while (m--) {
		int u, v;
		cin >> u >> v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	for (int i = 1; i <= n; i++)
		if (!was[i])
			ans += (isCycle(i) ? 0 : 1);
	cout << ans;
	return 0;
}


//bayemirov
#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

typedef long long ll;

#define pb push_back

const int N = 2e5;

vector<int> adj[N];
int n, m, ans;
bool was[N];

bool isCycle(int v, int pr = 0, bool res = 0) {
	was[v] = 1;
	for (auto to : adj[v]) {
		if (to == pr) continue;
		if (!was[to])
			res |= isCycle(to, v);
	  	else return 1;
	}
	return res;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	while (m--) {
		int u, v;
		cin >> u >> v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	for (int i = 1; i <= n; i++)
		if (!was[i])
			ans += (isCycle(i) ? 0 : 1);
	cout << ans;
	return 0;
}


//bayemirov
#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

typedef long long ll;

#define pb push_back

const int N = 2e5;

vector<int> adj[N];
int n, m, ans;
bool was[N];

bool isCycle(int v, int pr = 0) {
	was[v] = 1;
	for (auto to : adj[v]) {
		if (to == pr) continue;
		if (!was[to])
			isCycle(to, v);
	  	else return 1;
	}
	return 0;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	while (m--) {
		int u, v;
		cin >> u >> v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	for (int i = 1; i <= n; i++)
		if (!was[i])
			ans += (isCycle(i) && adj[i].size() > 0 ? 0 : 1);
	cout << ans;
	return 0;
}


//bayemirov
#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

typedef long long ll;

#define pb push_back

const int N = 2e5;

vector<int> adj[N];
int n, m, ans;
bool was[N];

bool isCycle(int v, int pr = 0) {
	was[v] = 1;
	for (auto to : adj[v]) {
		if (!was[to])
			isCycle(to, v);
		else if (to != pr) return 1;
	}
	return 0;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	while (m--) {
		int u, v;
		cin >> u >> v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	for (int i = 1; i <= n; i++)
		if (!was[i])
			ans += (isCycle(i) ? 0 : 1);
	cout << ans;
	return 0;
}


//bayemirov
#include <bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

typedef long long ll;

#define pb push_back

const int N = 2e5;

vector<int> adj[N];
int n, m, ans;
bool was[N];

bool isCycle(int v, int pr = 0) {
	was[v] = 1;
	for (auto to : adj[v]) {
		if (!was[to])
			isCycle(to, v);
		else if (to != pr) return 1;
	}
	return 0;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	while (m--) {
		int u, v;
		cin >> u >> v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	for (int i = 1; i <= n; i++)
		if (!was[i])
			ans += (isCycle(i) && adj[i].size() > 0 ? 0 : 1);
	cout << ans;
	return 0;
}


#include<iostream>
#include<bits/stdc++.h>
#include<vector>
#include<climits>
#include<string>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n,m;cin>>n>>m;
    vector<int> g[n+1];
    // for(int i=0;i<=n;i++)
    // {
    //     vector<int> te;
    //     for(int j=0;j<=n;j++)
    //         te.push_back(0);
    //     g.push_back(te);
    // }
    int edges[n+1]={0};
    for(int i=0;i<m;i++)
    {
        int src,des;cin>>src>>des;
        g[src].push_back(des);
        g[des].push_back(src);
        edges[src]+=1;
        edges[des]+=1;
    }
    int sep=0;int vis=0;
    while(vis<n)
    {
        vis++;
        int min=INT_MAX;int mini;
        int max=INT_MIN;
        for(int i=1;i<=n;i++)
        {
            if(edges[i]<min)
            {
                min=edges[i];
                mini=i;
            }
            if(edges[i]>max)
            {
                max=edges[i];
            }
        }
        if(min==1 && max==2)
        {
            break;
        }
//        cout<<min<<" "<<mini<<endl;
        if(min>=2)
            break;
        else
        {
            if(min==0)
            {
                sep++;
                edges[mini]=INT_MAX;
                continue;
            }
            // src is found and is mini
            // connected node to br found
            int des;int src=mini;
            des = g[src][0];
//            cout<<"des: "<<des<<endl;
            edges[src]=INT_MAX;
            edges[des]-=1;
            vector<int>::iterator it;
            it = g[des].begin();
            for (; it != g[des].end(); ++it)
            {
                if(*it == src)
                {
//                	cout<<"to delete "<<*it<<endl;
                    break;
				}
            }
//			cout<<"before del"<<endl;
            g[des].erase(it);
//            cout<<"after del"<<endl;
        }
    }
    cout<<sep<<"\n";
	return 0;
}


#include<iostream>
#include<bits/stdc++.h>
#include<vector>
#include<climits>
#include<string>
using namespace std;

vector<int> g[100002];
int cycle=0;

void dfs(int src,int visited[],int parent)
{
    visited[src]=1;
    for(int i=0;i<g[src].size();i++)
    {
        if(visited[g[src][i]]==0)
        {
//        	cout<<g[src][i]<<endl;
            dfs(g[src][i],visited,src);
        }
        else if(g[src][i]!=parent)
        {
//        	cout<<"cycle with parent\n"<<parent<<" and node "<<g[src][i]<<"\n";
            cycle=1;
        }
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n,m;cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int src,des;cin>>src>>des;
        g[src].push_back(des);
        g[des].push_back(src);
        // edges[src]+=1;
        // edges[des]+=1;
    }
    int sep=0;
    int visited[n+1]={0};
//    for(int i=1;i<=n;i++)
//    cout<<visited[i]<<" ";
//    cout<<'\n';
    for(int i=1;i<=n;i++)
    {
        if(visited[i]==0)
        {
            dfs(i,visited,-1);
            if(cycle==0)
                sep++;
            cycle=0;
        }
    }

    cout<<sep<<"\n";
    return 0;
}

/*
#include<iostream>
#include<bits/stdc++.h>
#include<vector>
#include<climits>
#include<string>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n,m;cin>>n>>m;
    vector<int> g[n+1];
    // for(int i=0;i<=n;i++)
    // {
    //     vector<int> te;
    //     for(int j=0;j<=n;j++)
    //         te.push_back(0);
    //     g.push_back(te);
    // }
    int edges[n+1]={0};
    for(int i=0;i<m;i++)
    {
        int src,des;cin>>src>>des;
        g[src].push_back(des);
        g[des].push_back(src);
        edges[src]+=1;
        edges[des]+=1;
    }
    int sep=0;int vis=0;
    while(vis<n)
    {
        vis++;
        int min=INT_MAX;int mini;
        int max=INT_MIN;
        for(int i=1;i<=n;i++)
        {
            if(edges[i]<min)
            {
                min=edges[i];
                mini=i;
            }
            if(edges[i]>max)
            {
                max=edges[i];
            }
        }
        if(min==1 && max==2)
        {
        	sep++;
            break;
        }
//        cout<<min<<" "<<mini<<endl;
        if(min>=2)
            break;
        else
        {
            if(min==0)
            {
                sep++;
                edges[mini]=INT_MAX;
                continue;
            }
            // src is found and is mini
            // connected node to br found
            int des;int src=mini;
            des = g[src][0];
//            cout<<"des: "<<des<<endl;
            edges[src]=INT_MAX;
            edges[des]-=1;
            vector<int>::iterator it;
            it = g[des].begin();
            for (; it != g[des].end(); ++it)
            {
                if(*it == src)
                {
//                	cout<<"to delete "<<*it<<endl;
                    break;
				}
            }
//			cout<<"before del"<<endl;
            g[des].erase(it);
//            cout<<"after del"<<endl;
        }
    }
    cout<<sep<<"\n";
	return 0;
}
*/


#include<iostream>
#include<bits/stdc++.h>
#include<vector>
#include<climits>
#include<string>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int y;

    int n,m;cin>>n>>m;
    vector<vector<int>> g;
    for(int i=0;i<=n;i++)
    {
        vector<int> te;
        for(int j=0;j<=n;j++)
            te.push_back(0);
        g.push_back(te);
    }
    int edges[n+1]={0};
    for(int i=0;i<m;i++)
    {
        int src,des;cin>>src>>des;
        g[src][des]=1;
        g[des][src]=1;
        edges[src]+=1;
        edges[des]+=1;
    }
    int sep=0;int vis=0;
    while(vis<n)
    {
        vis++;
        int min=INT_MAX;int mini;
        for(int i=1;i<=n;i++)
        {
            if(edges[i]<min)
            {
                min=edges[i];
                mini=i;
            }
        }
        if(min>=2)
            break;
        else
        {
            if(min==0)
            {
                sep++;
                edges[mini]=INT_MAX;
                continue;
            }
            // src is found and is mini
            // connected node to br found
            int des;int src=mini;
            for(int i=1;i<=n;i++)
            {
                if(g[mini][i]==1)
                {
                    des=i;
                    break;
                }
            }
            edges[src]=INT_MAX;
            edges[des]-=1;
            g[des][src]=0;
        }
    }
    cout<<sep<<"\n";
	return 0;
}


#include<iostream>
#include<bits/stdc++.h>
#include<vector>
#include<climits>
#include<string>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n,m;cin>>n>>m;
    vector<int> g[n+1];
    // for(int i=0;i<=n;i++)
    // {
    //     vector<int> te;
    //     for(int j=0;j<=n;j++)
    //         te.push_back(0);
    //     g.push_back(te);
    // }
    int edges[n+1]={0};
    for(int i=0;i<m;i++)
    {
        int src,des;cin>>src>>des;
        g[src].push_back(des);
        g[des].push_back(src);
        edges[src]+=1;
        edges[des]+=1;
    }
    int sep=0;int vis=0;
    while(vis<n)
    {
        vis++;
        int min=INT_MAX;int mini;
        int max=INT_MIN;
        for(int i=1;i<=n;i++)
        {
            if(edges[i]<min)
            {
                min=edges[i];
                mini=i;
            }
            if(edges[i]>max)
            {
                max=edges[i];
            }
        }
        if(min==1 && max==2)
        {
        	sep++;
            break;
        }
//        cout<<min<<" "<<mini<<endl;
        if(min>=2)
            break;
        else
        {
            if(min==0)
            {
                sep++;
                edges[mini]=INT_MAX;
                continue;
            }
            // src is found and is mini
            // connected node to br found
            int des;int src=mini;
            des = g[src][0];
//            cout<<"des: "<<des<<endl;
            edges[src]=INT_MAX;
            edges[des]-=1;
            vector<int>::iterator it;
            it = g[des].begin();
            for (; it != g[des].end(); ++it)
            {
                if(*it == src)
                {
//                	cout<<"to delete "<<*it<<endl;
                    break;
				}
            }
//			cout<<"before del"<<endl;
            g[des].erase(it);
//            cout<<"after del"<<endl;
        }
    }
    cout<<sep<<"\n";
	return 0;
}


#include<iostream>
#include<bits/stdc++.h>
#include<vector>
#include<climits>
#include<string>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n,m;cin>>n>>m;
    vector<vector<int>> g;
    for(int i=0;i<=n;i++)
    {
        vector<int> te;
        for(int j=0;j<=n;j++)
            te.push_back(0);
        g.push_back(te);
    }
    int edges[n+1]={0};
    for(int i=0;i<m;i++)
    {
        int src,des;cin>>src>>des;
        g[src][des]=1;
        g[des][src]=1;
        edges[src]+=1;
        edges[des]+=1;
    }
    int sep=0;int vis=0;
    while(vis<n)
    {
        vis++;
        int min=INT_MAX;int mini;
        for(int i=1;i<=n;i++)
        {
            if(edges[i]<min)
            {
                min=edges[i];
                mini=i;
            }
        }
        if(min>=2)
            break;
        else
        {
            if(min==0)
            {
                sep++;
                edges[mini]=INT_MAX;
                continue;
            }
            // src is found and is mini
            // connected node to br found
            int des;int src=mini;
            for(int i=1;i<=n;i++)
            {
                if(g[mini][i]==1)
                {
                    des=i;
                    break;
                }
            }
            edges[src]=INT_MAX;
            edges[des]-=1;
            g[des][src]=0;
        }
    }
    cout<<sep<<"\n";
	return 0;
}


#include<iostream>
#include<bits/stdc++.h>
#include<vector>
#include<climits>
#include<string>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n,m;cin>>n>>m;
    vector<int> g[n+1];
    // for(int i=0;i<=n;i++)
    // {
    //     vector<int> te;
    //     for(int j=0;j<=n;j++)
    //         te.push_back(0);
    //     g.push_back(te);
    // }
    int edges[n+1]={0};
    for(int i=0;i<m;i++)
    {
        int src,des;cin>>src>>des;
        g[src].push_back(des);
        g[des].push_back(src);
        edges[src]+=1;
        edges[des]+=1;
    }
    int sep=0;int vis=0;
    while(vis<n)
    {
        vis++;
        int min=INT_MAX;int mini;
        for(int i=1;i<=n;i++)
        {
            if(edges[i]<min)
            {
                min=edges[i];
                mini=i;
            }
        }
//        cout<<min<<" "<<mini<<endl;
        if(min>=2)
            break;
        else
        {
            if(min==0)
            {
                sep++;
                edges[mini]=INT_MAX;
                continue;
            }
            // src is found and is mini
            // connected node to br found
            int des;int src=mini;
            des = g[src][0];
//            cout<<"des: "<<des<<endl;
            edges[src]=INT_MAX;
            edges[des]-=1;
            vector<int>::iterator it;
            it = g[des].begin();
            for (; it != g[des].end(); ++it)
            {
                if(*it == src)
                {
//                	cout<<"to delete "<<*it<<endl;
                    break;
				}
            }
//			cout<<"before del"<<endl;
            g[des].erase(it);
//            cout<<"after del"<<endl;
        }
    }
    cout<<sep<<"\n";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pi 3.14159265359
#define int long long
#define pii pair<int,int>
#define ld long double
const int mod=1e9 +7;

int dx[] = {-1, 0, 1, 0};
int dy[] = { 0,-1, 0, 1};

vector<int>g[100005];
vector<bool>vis(100005,0);

void dfs(int x,int &e,int &v)
{
    if(!vis[x])v++;
    vis[x]=1;
    e+=g[x].size();
    for(auto i : g[x])
    {
        if(!vis[i])
        dfs(i,e,v);

    }
}

int32_t main()
{
     ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

   // freopen("input.txt", "rt", stdin);
  //freopen("output.txt", "wt", stdout);
  int n,m;
  cin>>n>>m;

  for(int i=0;i<m;i++)
  {
      int x,y;
      cin>>x>>y;
      g[y].push_back(x);
      g[x].push_back(y);
  }
  int ans=0;
  for(int i=1;i<=n;i++)
  {
      if(!vis[i])
      {
          int e=0,v=0;
           dfs(i,e,v);
           if(e<=v-1)
           ans++;
      }

  }
    cout<<ans;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int,int>
#define ld long double
const int mod=1e9 +7;

vector<int>g[100005];
vector<bool>vis(100005,0);

void dfs(int x,int &e,int &v)
{
    if(!vis[x])v++;
    vis[x]=1;
    e+=g[x].size();
    for(auto i : g[x])
    {
        if(!vis[i]){
        dfs(i,e,v);
    }

    }
}

int32_t main()
{
	ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

  #ifndef ONLINE_JUDGE
  freopen("input.txt", "rt", stdin);
  freopen("output.txt", "wt", stdout);
  #endif

  int n,m;
  cin>>n>>m;

  for(int i=0;i<m;i++)
  {
      int x,y;
      cin>>x>>y;
      g[y].push_back(x);
      g[x].push_back(y);
  }
  int ans=0;
  for(int i=1;i<=n;i++)
  {
      if(!vis[i])
      {
          int e=0,v=0;
           dfs(i,e,v);
           e/=2;
           if(e<=v-1)
           ans++;
      }

  }
    cout<<ans;

}


#include<bits/stdc++.h>
using namespace std;
#define pi 3.14159265359
#define int long long
#define pii pair<int,int>
#define ld long double
const int mod=1e9 +7;

int dx[] = {-1, 0, 1, 0};
int dy[] = { 0,-1, 0, 1};

vector<int>g[100005];
vector<bool>vis(100005,0);

void dfs(int x,int &e,int &v)
{
    if(!vis[x])v++;
    vis[x]=1;
    e+=g[x].size();
    for(auto i : g[x])
    {
        if(!vis[i]){
        e--;
        dfs(i,e,v);
    }

    }
}

int32_t main()
{
     ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

   // freopen("input.txt", "rt", stdin);
  //freopen("output.txt", "wt", stdout);
  int n,m;
  cin>>n>>m;

  for(int i=0;i<m;i++)
  {
      int x,y;
      cin>>x>>y;
      g[y].push_back(x);
      g[x].push_back(y);
  }
  int ans=0;
  for(int i=1;i<=n;i++)
  {
      if(!vis[i])
      {
          int e=0,v=0;
           dfs(i,e,v);
           if(e<=v-1)
           ans++;
      }

  }
    cout<<ans;
}


#include <bits/stdc++.h>
#define loop(i, n) for(int i=0;i<n;i++)
#define loopto(n) for(int i=0;i<n;i++)
#define loopft(i, x, y) for(int i=x;i<y;i++)
#define f first
#define s second
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;

using namespace std;

template<class T>           inline int sz(T a) { return a.size(); }
template<class T, class T2> inline bool chkmax(T &x, const T2 & y) { return x < y ? x = y, 1 : 0; }
template<class T, class T2> inline bool chkmin(T &x, const T2 & y) { return x > y ? x = y, 1 : 0; }
template<class T, class T2> inline istream &operator>>(istream &is,       pair<T, T2> &p)             { is>>p.f>>p.s;      return is; }
template<class T, class T2> inline ostream &operator<<(ostream &os, const pair<T, T2> &p)             { os<<p.f<<' '<<p.s; return os; }
template<class T>           inline istream &operator>>(istream &is,       vector<T> &v)               { for (auto &curr : v) is>>curr;      return is; }
template<class T>           inline ostream &operator<<(ostream &os, const vector<T> &v)               { for (auto curr : v)  os<<curr<<' '; return os; }
template<class T, class T2> inline ostream &operator<<(ostream &os, const map<T, T2> &m)              { auto id = m.begin();   while (id != m.end())   os<<(*id).f<<' '<<(*(id++)).s; return os; }
template<class T, class T2> inline ostream &operator<<(ostream &os, const unordered_map<T, T2> &um)   { auto id = um.begin();  while (id != um.end())  os<<(*id).f<<' '<<(*(id++)).s; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const list<T> &l)                 { auto id = l.begin();   while (id != l.end())   os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const set<T> &s)                  { auto id = s.begin();   while (id != s.end())   os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const unordered_set<T> &us)       { auto id = us.begin();  while (id != us.end())  os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const multiset<T> &ms)            { auto id = ms.begin();  while (id != ms.end())  os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const unordered_multiset<T> &mus) { auto id = mus.begin(); while (id != mus.end()) os<<*(id++)<<' '; return os; }
template<class T>           void inArray (T a[], const int &n) { for (int i=0; i<n; i++) cin>>a[i];       }
template<class T>           void outArray(T a[], const int &n) { for (int i=0; i<n; i++) cout<<a[i]<<' '; }

const int MAXN = 1e5 + 100;
int n, m;
vector<pair<int, int>> con[MAXN];
vector<bool> in;
int ans;

void input()
{
    int x, y;
    cin>>n>>m;
    in.resize(n, 0);
    loopto (m)
    {
        cin>>x>>y;
        con[x-1].pb({y-1, sz(con[y-1])});
        con[y-1].pb({x-1, sz(con[x-1])-1});
    }
}

void output()
{
    cout<<ans<<'\n';
}

void deleteEdge(pair<int, int> curr)
{
    if (sz(con[curr.f]) > 1)
    {
        auto temp = con[curr.f].back();
        con[temp.f][temp.s].s = curr.s;
        swap(con[curr.f][curr.s], con[curr.f].back());
    }
    con[curr.f].pop_back();
}

void update(int curr)
{
    in[curr] = 1;
    pair<int, int> to = con[curr][0];
    deleteEdge(to);
    deleteEdge({curr, 0});
    if (sz(con[to.f]) == 1)
        update(to.f);
}

void solve()
{
    ans = n;
    for (int i=0; i<n; i++)
    {
        if (sz(con[i]) == 1)
            update(i);
    }
    for (int i=0; i<n; i++)
    {
        if (!con[i].empty())
            update(i);
    }
    for (int i=0; i<n; i++)
    {
        ans -= in[i];
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    input();
    solve();
    output();
    return 0;
}


#include <bits/stdc++.h>
#define loop(i, n) for(int i=0;i<n;i++)
#define loopto(n) for(int i=0;i<n;i++)
#define loopft(i, x, y) for(int i=x;i<y;i++)
#define f first
#define s second
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;

using namespace std;

template<class T>           inline int sz(T a) { return a.size(); }
template<class T, class T2> inline bool chkmax(T &x, const T2 & y) { return x < y ? x = y, 1 : 0; }
template<class T, class T2> inline bool chkmin(T &x, const T2 & y) { return x > y ? x = y, 1 : 0; }
template<class T, class T2> inline istream &operator>>(istream &is,       pair<T, T2> &p)             { is>>p.f>>p.s;      return is; }
template<class T, class T2> inline ostream &operator<<(ostream &os, const pair<T, T2> &p)             { os<<p.f<<' '<<p.s; return os; }
template<class T>           inline istream &operator>>(istream &is,       vector<T> &v)               { for (auto &curr : v) is>>curr;      return is; }
template<class T>           inline ostream &operator<<(ostream &os, const vector<T> &v)               { for (auto curr : v)  os<<curr<<' '; return os; }
template<class T, class T2> inline ostream &operator<<(ostream &os, const map<T, T2> &m)              { auto id = m.begin();   while (id != m.end())   os<<(*id).f<<' '<<(*(id++)).s; return os; }
template<class T, class T2> inline ostream &operator<<(ostream &os, const unordered_map<T, T2> &um)   { auto id = um.begin();  while (id != um.end())  os<<(*id).f<<' '<<(*(id++)).s; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const list<T> &l)                 { auto id = l.begin();   while (id != l.end())   os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const set<T> &s)                  { auto id = s.begin();   while (id != s.end())   os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const unordered_set<T> &us)       { auto id = us.begin();  while (id != us.end())  os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const multiset<T> &ms)            { auto id = ms.begin();  while (id != ms.end())  os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const unordered_multiset<T> &mus) { auto id = mus.begin(); while (id != mus.end()) os<<*(id++)<<' '; return os; }
template<class T>           void inArray (T a[], const int &n) { for (int i=0; i<n; i++) cin>>a[i];       }
template<class T>           void outArray(T a[], const int &n) { for (int i=0; i<n; i++) cout<<a[i]<<' '; }

const int MAXN = 1e5 + 100;
int n, m;
vector<pair<int, int>> con[MAXN];
vector<bool> used;
int ans;

void input()
{
    int x, y;
    cin>>n>>m;
    used.resize(n, 0);
    loopto (m)
    {
        cin>>x>>y;
        con[x-1].pb({y-1, sz(con[y-1])});
        con[y-1].pb({x-1, sz(con[x-1])-1});
    }
}

void output()
{
    cout<<ans<<'\n';
}

void deleteEdge(pair<int, int> curr)
{
    auto temp = con[curr.f].back();
    con[temp.f][temp.s].s = curr.s;
    swap(con[curr.f][curr.s], con[curr.f].back());
    con[curr.f].pop_back();
}

void update(int curr)
{
    used[curr] = 1;
    pair<int, int> to = con[curr][0];
    deleteEdge(to);
    deleteEdge({curr, 0});
    if (sz(con[to.f]) == 1)
        update(to.f);
}

void solve()
{
    ans = n;
    for (int i=0; i<n; i++)
    {
        if (sz(con[i]) == 1)
            update(i);
    }
    for (int i=0; i<n; i++)
    {
        if (sz(con[i]))
            update(i);
    }
    for (int i=0; i<n; i++)
    {
        ans -= used[i];
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    input();
    solve();
    output();
    return 0;
}


#include <bits/stdc++.h>
#define loop(i, n) for(int i=0;i<n;i++)
#define loopto(n) for(int i=0;i<n;i++)
#define loopft(i, x, y) for(int i=x;i<y;i++)
#define f first
#define s second
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;

using namespace std;

template<class T>           inline int sz(T a) { return a.size(); }
template<class T, class T2> inline bool chkmax(T &x, const T2 & y) { return x < y ? x = y, 1 : 0; }
template<class T, class T2> inline bool chkmin(T &x, const T2 & y) { return x > y ? x = y, 1 : 0; }
template<class T, class T2> inline istream &operator>>(istream &is,       pair<T, T2> &p)             { is>>p.f>>p.s;      return is; }
template<class T, class T2> inline ostream &operator<<(ostream &os, const pair<T, T2> &p)             { os<<p.f<<' '<<p.s; return os; }
template<class T>           inline istream &operator>>(istream &is,       vector<T> &v)               { for (auto &curr : v) is>>curr;      return is; }
template<class T>           inline ostream &operator<<(ostream &os, const vector<T> &v)               { for (auto curr : v)  os<<curr<<' '; return os; }
template<class T, class T2> inline ostream &operator<<(ostream &os, const map<T, T2> &m)              { auto id = m.begin();   while (id != m.end())   os<<(*id).f<<' '<<(*(id++)).s; return os; }
template<class T, class T2> inline ostream &operator<<(ostream &os, const unordered_map<T, T2> &um)   { auto id = um.begin();  while (id != um.end())  os<<(*id).f<<' '<<(*(id++)).s; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const list<T> &l)                 { auto id = l.begin();   while (id != l.end())   os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const set<T> &s)                  { auto id = s.begin();   while (id != s.end())   os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const unordered_set<T> &us)       { auto id = us.begin();  while (id != us.end())  os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const multiset<T> &ms)            { auto id = ms.begin();  while (id != ms.end())  os<<*(id++)<<' '; return os; }
template<class T>           inline ostream &operator<<(ostream &os, const unordered_multiset<T> &mus) { auto id = mus.begin(); while (id != mus.end()) os<<*(id++)<<' '; return os; }
template<class T>           void inArray (T a[], const int &n) { for (int i=0; i<n; i++) cin>>a[i];       }
template<class T>           void outArray(T a[], const int &n) { for (int i=0; i<n; i++) cout<<a[i]<<' '; }

const int MAXN = 1e5 + 100;
int n, m;
vector<pair<int, int>> con[MAXN];
vector<bool> used;
int ans;

void input()
{
    int x, y;
    cin>>n>>m;
    used.resize(n, 0);
    loopto (m)
    {
        cin>>x>>y;
        con[x-1].pb({y-1, sz(con[y-1])});
        con[y-1].pb({x-1, sz(con[x-1])-1});
    }
}

void output()
{
    cout<<ans<<'\n';
}

void deleteEdge(pair<int, int> curr)
{
    swap(con[curr.f][curr.s], con[curr.f].back());
    con[curr.f].pop_back();
}

void update(int curr)
{
    used[curr] = 1;
    pair<int, int> to = con[curr][0];
    deleteEdge(to);
    deleteEdge({curr, 0});
    if (sz(con[to.f]) == 1)
        update(to.f);
}

void solve()
{
    ans = n;
    for (int i=0; i<n; i++)
    {
        if (sz(con[i]) == 1)
            update(i);
    }
    for (int i=0; i<n; i++)
    {
        if (sz(con[i]))
            update(i);
    }
    for (int i=0; i<n; i++)
    {
        ans -= used[i];
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    input();
    solve();
    output();
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define sf(n) scanf("%lld",&n)
#define pi acos(-1)
#define filein freopen("input.txt","r",stdin)
#define fileout freopen("output.txt","w",stdout)
using namespace std;
vector<int> v[1000000];
int visit[1000000];
int k;
void dfs(int start,int parent)
{
    if(visit[start]) return ;
    visit[start]=true;
    for(auto x: v[start])
    {

        if(visit[x]==true and x!=parent)
        {
            k=0;
        }
        dfs(x,start);
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
    }
    int ans=0;
    for(int i=1;i<=m;i++)
    {

        if(visit[i]==false)
        {
            k=1;
            dfs(i,-1);
            ans+=k;

        }
    }
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define sf(n) scanf("%lld",&n)
#define pi acos(-1)
#define filein freopen("input.txt","r",stdin)
#define fileout freopen("output.txt","w",stdout)
using namespace std;
vector<int> v[1000000];
int visit[1000000];
int k;
void dfs(int start,int parent)
{
    visit[start]=true;
    for(auto x: v[start])
    {

        if(visit[x]==true and x!=parent)
        {
            k=0;
        }
        if(visit[x]==false)
        {
            dfs(x,start);
        }
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {

        if(visit[i]==false)
        {
            k=1;
            dfs(i,-1);
            ans+=k;

        }
    }
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define sf(n) scanf("%lld",&n)
#define pi acos(-1)
#define filein freopen("input.txt","r",stdin)
#define fileout freopen("output.txt","w",stdout)
using namespace std;
vector<int> v[1000000];
int visit[1000000];
int k;
void dfs(int start,int parent)
{
    visit[start]=true;
    for(auto x: v[start])
    {

        if(visit[x]==true and x!=parent)
        {
            k=0;
        }
        if(visit[x]==false)
        {
            dfs(x,start);
        }
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
    }
    int ans=0;
    for(int i=1;i<=m;i++)
    {

        if(visit[i]==false)
        {
            k=1;
            dfs(i,-1);
            ans+=k;

        }
    }
    cout<<ans<<endl;
}


#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define sf(n) scanf("%lld",&n)
#define pi acos(-1)
#define filein freopen("input.txt","r",stdin)
#define fileout freopen("output.txt","w",stdout)
using namespace std;
vector<int> v[1000000];
int visit[1000000];
int k;
void dfs(int start,int parent)
{
    if(visit[start]) return ;
    visit[start]=true;
    for(auto x: v[start])
    {

        if(visit[x]==true and x!=parent)
        {
            k=0;
        }
        dfs(x,start);
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {

        if(visit[i]==false)
        {
            k=1;
            dfs(i,-1);
            ans+=k;

        }
    }
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long int ll;
#define ios ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define endl "\n"
#define deb(x) cout<<"Debug\t"<<#x<<"="<<x<<endl;
#define deb2(x,y) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<endl;
#define deb3(x,y,z) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<"\t"<<#z<<"="<<z<<endl;
#define deb4(x,y,z,w) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<"\t"<<#z<<"="<<z<<"\t"<<#w<<"="<<w<<endl;
#define mod 1000000007
#define vi vector<ll>
#define pll pair<ll,ll>
#define vivi vector<vector<ll>>
#define vipa vector<pair<ll,ll>>
#define pb push_back
#define pf push_front
#define pll pair<ll,ll>

vi adj[100004];
bool vis[100004];
//map<ll,ll> mp;
ll arr[100004];
vi curr;
//set<ll> st;

void dfs(ll x,ll par=0)
{
    //cout<<"Dfs   "<<x<<"\t"<<par<<endl;;
    vis[x]=true;
    //st.insert(x);
    curr.pb(x);
    arr[x]++;
    for(auto z:adj[x])
    {
        if(!vis[z])
        dfs(z,x);
        else if(z!=par)
        arr[z]++;
    }
}
int main()
{
    ios;
    ll t,i,n,m,j,x,y,pos,temp,ans,sum,mini,k,diff,maxi;string s;bool flag;
    cin>>n>>m;

    while(m--)
    cin>>x>>y,adj[x].pb(y),adj[y].pb(x);

    memset(vis,false,sizeof(vis));
    memset(arr,0,sizeof(arr));

    ans=0;
    for(i=1;i<=n;i++)
    if(!vis[i])
    {
        curr.clear();
        dfs(i);
        flag=false;
        //for(auto z:st)
       // deb2(z,mp[z]);
        for(auto z:curr)
        if(arr[z]>1)
        {
            flag=true;
            break;
        }
        if(!flag)
        ans++;
    }
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long int ll;
#define ios ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define endl "\n"
#define deb(x) cout<<"Debug\t"<<#x<<"="<<x<<endl;
#define deb2(x,y) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<endl;
#define deb3(x,y,z) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<"\t"<<#z<<"="<<z<<endl;
#define deb4(x,y,z,w) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<"\t"<<#z<<"="<<z<<"\t"<<#w<<"="<<w<<endl;
#define mod 1000000007
#define vi vector<ll>
#define pll pair<ll,ll>
#define vivi vector<vector<ll>>
#define vipa vector<pair<ll,ll>>
#define pb push_back
#define pf push_front
#define pll pair<ll,ll>

vi adj[100004];
bool vis[100004];
bool flag;

void dfs(ll x,ll par=0)
{
    vis[x]=true;
    for(auto z:adj[x])
    if(!vis[z])
    dfs(z,x);
    else if(z!=par)
    flag=true;

}
int main()
{
    ios;
    ll t,i,n,m,j,x,y,pos,temp,ans,sum,mini,k,diff,maxi;string s;
    cin>>n>>m;

    while(m--)
    cin>>x>>y,adj[x].pb(y),adj[y].pb(x);

    memset(vis,false,sizeof(vis));
    ans=0;
    for(i=1;i<=n;i++)
    if(!vis[i])
    {
        flag=false;
        dfs(i);
        if(!flag)
        ans++;
    }
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long int ll;
#define ios ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define endl "\n"
#define deb(x) cout<<"Debug\t"<<#x<<"="<<x<<endl;
#define deb2(x,y) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<endl;
#define deb3(x,y,z) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<"\t"<<#z<<"="<<z<<endl;
#define deb4(x,y,z,w) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<"\t"<<#z<<"="<<z<<"\t"<<#w<<"="<<w<<endl;
#define mod 1000000007
#define vi vector<ll>
#define pll pair<ll,ll>
#define vivi vector<vector<ll>>
#define vipa vector<pair<ll,ll>>
#define pb push_back
#define pf push_front
#define pll pair<ll,ll>

vi adj[100004];
bool vis[100004];
//map<ll,ll> mp;
ll arr[100004];
vi curr;
//set<ll> st;
bool flag;

void dfs(ll x,ll par=0)
{
    //cout<<"Dfs   "<<x<<"\t"<<par<<endl;;
    vis[x]=true;
    //st.insert(x);
    //curr.pb(x);
    arr[x]++;
    for(auto z:adj[x])
    {
        if(!vis[z])
        dfs(z,x);
        else if(z!=par)
        flag=true;
    }
}
int main()
{
    ios;
    ll t,i,n,m,j,x,y,pos,temp,ans,sum,mini,k,diff,maxi;string s;
    cin>>n>>m;

    while(m--)
    cin>>x>>y,adj[x].pb(y),adj[y].pb(x);

    memset(vis,false,sizeof(vis));
    memset(arr,0,sizeof(arr));

    ans=0;
    for(i=1;i<=n;i++)
    if(!vis[i])
    {
        //curr.clear();
        flag=false;
        dfs(i);

        //for(auto z:st)
       // deb2(z,mp[z]);
        //for(auto z:curr)
        //if(arr[z]>1)
        //{
        //    flag=true;
        //    break;
        //}
        if(!flag)
        ans++;
    }
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long int ll;
#define ios ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define endl "\n"
#define deb(x) cout<<"Debug\t"<<#x<<"="<<x<<endl;
#define deb2(x,y) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<endl;
#define deb3(x,y,z) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<"\t"<<#z<<"="<<z<<endl;
#define deb4(x,y,z,w) cout<<"Debug\t"<<#x<<"="<<x<<"\t"<<#y<<"="<<y<<"\t"<<#z<<"="<<z<<"\t"<<#w<<"="<<w<<endl;
#define mod 1000000007
#define vi vector<ll>
#define pll pair<ll,ll>
#define vivi vector<vector<ll>>
#define vipa vector<pair<ll,ll>>
#define pb push_back
#define pf push_front
#define pll pair<ll,ll>

vi adj[100004];
bool vis[100004];
map<ll,ll> mp;
set<ll> st;

void dfs(ll x,ll par=0)
{
    //cout<<"Dfs   "<<x<<"\t"<<par<<endl;;
    vis[x]=true;
    st.insert(x);
    mp[x]++;
    for(auto z:adj[x])
    {
        if(!st.count(z))
        dfs(z,x);
        else if(z!=par)
        mp[z]++;
    }
}
int main()
{
    ios;
    ll t,i,n,m,j,x,y,pos,temp,ans,sum,mini,k,diff,maxi;string s;bool flag;
    cin>>n>>m;

    while(m--)
    cin>>x>>y,adj[x].pb(y),adj[y].pb(x);

    memset(vis,false,sizeof(vis));
    ans=0;
    for(i=1;i<=n;i++)
    if(!vis[i])
    {
        st.clear();
        dfs(i);
        flag=false;
        //for(auto z:st)
       // deb2(z,mp[z]);
        for(auto z:st)
        if(mp[z]>1)
        {
            flag=true;
            break;
        }
        if(!flag)
        ans++;
    }
    cout<<ans<<endl;
}


///╔══╗
///╚╗╔╝
///╔╝╚(¯`v´¯)
///╚══╝`.¸.´farzin

#include <bits/stdc++.h>

#define int int64_t
#define pb push_back
#define ibswsct ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define gcd __gcd
#define s second
#define f first
#define mp make_pair
typedef std::pair<int,int> pii ;

using namespace std;

const int N=1e5+10;
int n,m,x,y,ans;
vector<int> adj[N];
bool mark[N];

bool dfs (int v, int p, int f, bool w=true){
    mark[v]=true;
    for(int i=0;i<adj[v].size();i++){
        int u=adj[v][i];
        if(u==p){
            continue;
        }
        if(u==f){
            w=false;
        }
        if(!mark[u]){
            w&=dfs(u,v,f);
        }
    }
    return w;
}

int32_t main(){
	ibswsct
	cin>>n>>m;
	for(int i=0;i<m;i++){
        cin>>x>>y;
        adj[x].pb(y);
        adj[y].pb(x);
	}
	for(int i=1;i<=n;i++){
        if(!mark[i]){
            ans+=dfs(i,i,i);
        }
	}
	cout<<ans;
}


///╔══╗
///╚╗╔╝
///╔╝╚(¯`v´¯)
///╚══╝`.¸.´farzin

#include <bits/stdc++.h>

#define int int64_t
#define pb push_back
#define ibswsct ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define gcd __gcd
#define s second
#define f first
#define mp make_pair
typedef std::pair<int,int> pii ;

using namespace std;

const int N=1e5+10;
int n,m,x,y,ans;
vector<int> adj[N];
bool mark[N];

bool dfs (int v, int p, bool w=true){
    mark[v]=true;
    for(int i=0;i<adj[v].size();i++){
        int u=adj[v][i];
        if(u==p){
            continue;
        }
        if(!mark[u]){
            w&=dfs(u,v);
        }
        else{
            w=false;
        }
    }
    return w;
}

int32_t main(){
	ibswsct
	cin>>n>>m;
	for(int i=0;i<m;i++){
        cin>>x>>y;
        adj[x].pb(y);
        adj[y].pb(x);
	}
	for(int i=1;i<=n;i++){
        if(!mark[i]){
            ans+=dfs(i,i);
        }
	}
	cout<<ans;
}


///╔══╗
///╚╗╔╝
///╔╝╚(¯`v´¯)
///╚══╝`.¸.´farzin

#include <bits/stdc++.h>

#define int int64_t
#define pb push_back
#define ibswsct ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define gcd __gcd
#define s second
#define f first
#define mp make_pair
typedef std::pair<int,int> pii ;

using namespace std;

const int N=1e5+10;
int n,m,x,y,ans;
vector<int> adj[N];
bool mark[N];

bool dfs (int v, int p, int f, bool w=true){
    mark[v]=true;
    for(int i=0;i<adj[v].size();i++){
        int u=adj[v][i];
        if(u==p){
            continue;
        }
        if(!mark[u]){
            w&=dfs(u,v,f);
        }
        else{
            w=false;
        }
    }
    return w;
}

int32_t main(){
	ibswsct
	cin>>n>>m;
	for(int i=0;i<m;i++){
        cin>>x>>y;
        adj[x].pb(y);
        adj[y].pb(x);
	}
	for(int i=1;i<=n;i++){
        if(!mark[i]){
            ans+=dfs(i,i,i);
        }
	}
	cout<<ans;
}


#include <bits/stdc++.h>
using namespace std;
//#define ll long long
#define ll int
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);
unordered_map<ll,vector<ll>>seen;
//ll visited[100001];
bitset<1000001>visited;
ll parent[100001];
bool bfscycle(ll i)
{
    queue<ll>q;
    q.push(i);
    bool cyc=false;
    while(!q.empty())
    {
        ll f=q.front();
        q.pop();
        visited[f]=1;
        for(ll j=0;j<seen[f].size();j++)
        {
            if((visited[seen[f][j]]==1)&&parent[f]!=seen[f][j])
            {
                //cout<<f<<"-> "<<seen[f][j]<<'\n';
                cyc=true;
                //break;
            }
            if(visited[seen[f][j]]==0)
            {
                q.push(seen[f][j]);
                parent[seen[f][j]]=f;
            }
        }
    }
    return cyc;
}
int main(){
    // Your code here!
    ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
    ll n,m;
    cin>>n>>m;
    for(ll i=1;i<=m;i++)
    {
        ll a,b;
        cin>>a>>b;
        a--;
        b--;
        seen[a].push_back(b);
        seen[b].push_back(a);
    }
    for(ll i=0;i<n;i++)
    {
        visited[i]=false;
        parent[i]=-1;
    }
    ll cnt=0;
    for(ll i=0;i<n;i++)
    {
        if(visited[i]==0)
        {
            if(!bfscycle(i))
            {
                //cout<<i<<'\n';
                cnt++;
            }
        }
    }
    cout<<cnt;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);
unordered_map<ll,vector<ll>>seen;
//ll visited[100001];
bitset<1000001>visited;
ll parent[100001];
bool bfscycle(ll i)
{
    queue<ll>q;
    q.push(i);
    bool cyc=false;
    while(!q.empty())
    {
        ll f=q.front();
        q.pop();
        visited[f]=1;
        for(ll j=0;j<seen[f].size();j++)
        {
            if((visited[seen[f][j]]==1)&&parent[f]!=seen[f][j])
            {
                //cout<<f<<"-> "<<seen[f][j]<<'\n';
                cyc=true;
                //break;
            }
            if(visited[seen[f][j]]==0)
            {
                q.push(seen[f][j]);
                parent[seen[f][j]]=f;
            }
        }
    }
    return cyc;
}
int main(){
    // Your code here!
    ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
    ll n,m;
    cin>>n>>m;
    for(ll i=1;i<=m;i++)
    {
        ll a,b;
        cin>>a>>b;
        a--;
        b--;
        seen[a].push_back(b);
        seen[b].push_back(a);
    }
    for(ll i=0;i<n;i++)
    {
        visited[i]=false;
        parent[i]=-1;
    }
    ll cnt=0;
    for(ll i=0;i<n;i++)
    {
        if(visited[i]==0)
        {
            if(!bfscycle(i))
            {
                //cout<<i<<'\n';
                cnt++;
            }
        }
    }
    cout<<cnt;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
unordered_map<ll,vector<ll>>seen;
//ll visited[100001];
bitset<1000001>visited;
ll parent[100001];
bool bfscycle(ll i)
{
    queue<ll>q;
    q.push(i);
    bool cyc=false;
    while(!q.empty())
    {
        ll f=q.front();
        q.pop();
        visited[f]=1;
        for(ll j=0;j<seen[f].size();j++)
        {
            if((visited[seen[f][j]]==1)&&parent[f]!=seen[f][j])
            {
                //cout<<f<<"-> "<<seen[f][j]<<'\n';
                cyc=true;
                //break;
            }
            if(visited[seen[f][j]]==0)
            {
                q.push(seen[f][j]);
                parent[seen[f][j]]=f;
            }
        }
    }
    return cyc;
}
int main(){
    // Your code here!
    ll n,m;
    cin>>n>>m;
    for(ll i=1;i<=m;i++)
    {
        ll a,b;
        cin>>a>>b;
        a--;
        b--;
        seen[a].push_back(b);
        seen[b].push_back(a);
    }
    for(ll i=0;i<n;i++)
    {
        visited[i]=false;
        parent[i]=-1;
    }
    ll cnt=0;
    for(ll i=0;i<n;i++)
    {
        if(visited[i]==0)
        {
            if(!bfscycle(i))
            {
                //cout<<i<<'\n';
                cnt++;
            }
        }
    }
    cout<<cnt;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
unordered_map<ll,vector<ll>>seen;
ll visited[100001];
ll parent[100001];
bool bfscycle(ll i)
{
    queue<ll>q;
    q.push(i);
    bool cyc=false;
    while(!q.empty())
    {
        ll f=q.front();
        q.pop();
        visited[f]=true;
        for(ll j=0;j<seen[f].size();j++)
        {
            if(visited[seen[f][j]]&&parent[f]!=seen[f][j])
            {
                //cout<<f<<"-> "<<seen[f][j]<<'\n';
                cyc=true;
                //break;
            }
            if(!visited[seen[f][j]])
            {
                q.push(seen[f][j]);
                parent[seen[f][j]]=f;
            }
        }
    }
    return cyc;
}
int main(){
    // Your code here!
    ll n,m;
    cin>>n>>m;
    for(ll i=1;i<=m;i++)
    {
        ll a,b;
        cin>>a>>b;
        a--;
        b--;
        seen[a].push_back(b);
        seen[b].push_back(a);
    }
    for(ll i=0;i<n;i++)
    {
        visited[i]=false;
        parent[i]=-1;
    }
    ll cnt=0;
    for(ll i=0;i<n;i++)
    {
        if(!visited[i])
        {
            if(!bfscycle(i))
            {
                //cout<<i<<'\n';
                cnt++;
            }
        }
    }
    cout<<cnt;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
//#define ll int
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);
unordered_map<ll,vector<ll>>seen;
bool visited[100001];

ll parent[100001];
bool bfscycle(ll i)
{
    queue<ll>q;
    q.push(i);
    bool cyc=false;
    while(!q.empty())
    {
        ll f=q.front();
        q.pop();
        visited[f]=true;
        for(ll j=0;j<seen[f].size();j++)
        {
            if((visited[seen[f][j]])&&parent[f]!=seen[f][j])
            {
                //cout<<f<<"-> "<<seen[f][j]<<'\n';
                cyc=true;
                //break;
            }
            if(!visited[seen[f][j]])
            {
                q.push(seen[f][j]);
                parent[seen[f][j]]=f;
            }
        }
    }
    return cyc;
}
int main(){
    // Your code here!
    ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
    ll n,m;
    cin>>n>>m;
    for(ll i=1;i<=m;i++)
    {
        ll a,b;
        cin>>a>>b;
        a--;
        b--;
        seen[a].push_back(b);
        seen[b].push_back(a);
    }
    for(ll i=0;i<n;i++)
    {
        visited[i]=false;
        parent[i]=-1;
    }
    ll cnt=0;
    for(ll i=0;i<n;i++)
    {
        if(!visited[i])
        {
            if(!bfscycle(i))
            {
                //cout<<i<<'\n';
                cnt++;
            }
        }
    }
    cout<<cnt;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#define ll long long
#define ll int
#define F_I ios_base::sync_with_stdio(false);cin.tie(NULL);
unordered_map<ll,vector<ll>>seen;
bool visited[100001];

ll parent[100001];
bool bfscycle(ll i)
{
    queue<ll>q;
    q.push(i);
    bool cyc=false;
    while(!q.empty())
    {
        ll f=q.front();
        q.pop();
        visited[f]=true;
        for(ll j=0;j<seen[f].size();j++)
        {
            if((visited[seen[f][j]])&&parent[f]!=seen[f][j])
            {
                //cout<<f<<"-> "<<seen[f][j]<<'\n';
                cyc=true;
                //break;
            }
            if(!visited[seen[f][j]])
            {
                q.push(seen[f][j]);
                parent[seen[f][j]]=f;
            }
        }
    }
    return cyc;
}
int main(){
    // Your code here!
    ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
    ll n,m;
    cin>>n>>m;
    for(ll i=1;i<=m;i++)
    {
        ll a,b;
        cin>>a>>b;
        a--;
        b--;
        seen[a].push_back(b);
        seen[b].push_back(a);
    }
    for(ll i=0;i<n;i++)
    {
        visited[i]=false;
        parent[i]=-1;
    }
    ll cnt=0;
    for(ll i=0;i<n;i++)
    {
        if(!visited[i])
        {
            if(!bfscycle(i))
            {
                //cout<<i<<'\n';
                cnt++;
            }
        }
    }
    cout<<cnt;
    return 0;
}


#pragma GCC optimize("Ofast")

// #include <bits/stdc++.h>
#include <iostream>      // * Header that defines the standard input/output stream objects: [ cin, cout, cerr ]
#include <iomanip>       // * iomanip is a library that is used to manipulate the output of C++ program. [set_precision, set_time]
#include <cassert>       // * C Diagnostics Library -> assert.h defines one macro function that can be used as a standard debugging tool :
#include <cmath>         // * Header <cmath> declares a set of functions to compute common mathematical operations and transformations. Link: http://www.cplusplus.com/reference/cmath/
#include <cstdio>        // * Streams are handled in the cstdio library as pointers to FILE objects.
#include <cstring>       // * This header file defines several functions to manipulate C strings and arrays. Link: http://www.cplusplus.com/reference/cstring/
#include <cstdlib>       // * This header defines several general purpose functions, including dynamic memory management, random number generation, communication with the environment, integer arithmetics, searching, sorting and converting. Link : http://www.cplusplus.com/reference/cstdlib/
#include <map>           // * Header that defines the map and multimap container classes. Maps are typically implemented as BST. binary search trees.
#include <set>           // * Sets are typically implemented as binary search trees.
#include <stack>         // * template <class T, class Container = deque<T> > class stack;
#include <queue>         // * Link : https://en.cppreference.com/w/cpp/header/queue
#include <vector>        // * Constructs a vector, initializing its contents depending on the constructor version used.
#include <chrono>        // * The chrono library defines three main types as well as utility functions and common typedefs. clock, time points, durations.
#include <algorithm>     // * The header <algorithm> defines a collection of functions especially designed to be used on ranges of elements. Link : http://www.cplusplus.com/reference/algorithm/
#include <unordered_map> // *
#include <unordered_set> // *

using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
// Link : https://codeforces.com/blog/entry/11080
template <typename T>
using ordered_set = tree<
    T,
    null_type,
    less<T>,
    rb_tree_tag,
    tree_order_statistics_node_update>;
// ! order_of_key(x) : returns the number of values less than x
// ! find_by_order(k) : returns the iterator to kth largest element. (0-based)

#define int long long
#define pb push_back
#define endl "\n"
#define all(CON) (CON).begin(), (CON).end()
#define F first
#define S second
#define MP make_pair
#define sz(x) (int)x.size()
#define rp(i, n) for (int i = 0; i < n; i++)
#define fr(i, n) for (int i = 1; i <= n; i++)
#define ff(i, a, b) for (int i = a; i <= b; i++)
#define fff(i, a, b) for (int i = a; i < b; i++)
#define rrp(i, n) for (int i = n - 1; i >= 0; i--)
#define rfr(i, n) for (int i = n; i >= 1; i--)
#define onlyunique(v) v.erase(unique(v.begin(), v.end()), v.end()); // remove duplicates in a sorted vector

#define TRACE
#ifndef ONLINE_JUDGE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char *name, Arg1 &&arg1)
{
    cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&... args)
{
    const char *comma = strchr(names + 1, ',');
    cerr.write(names, comma - names) << " : " << arg1 << " || ";
    __f(comma + 1, args...);
}
#else
#define trace(...)
#endif

typedef long double ld;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<char> vc;
typedef vector<pair<int, int>> vpi;

const int mod = 1e9 + 7;
// const int mod = 998244353;
const long long inff = 2e18;
const int inf = 2e9;

int min(int x, int y) // * returns minimum of two numbers
{
    return y ^ ((x ^ y) & -(x < y));
}
int max(int x, int y) // * returns maximum of two numbers
{
    return x ^ ((x ^ y) & -(x < y));
}
// int abs(int n)
// {
//     int const mask = n >> (sizeof(int) * CHAR_BIT - 1);
//     return ((n ^ mask) - mask);
// }
int add(int a, int b) // * Recursive addition of integers
{
    if (b == 0)
        return a;
    int sum = a ^ b;
    int carry = (a & b) << 1;
    return add(sum, carry);
}
int Add(int a, int b) // * Iterative addition of two integers
{
    while (b != 0)
    {
        int sum = a ^ b;
        int carry = (a & b) << 1;
        a = sum;
        b = carry;
    }
    return a;
}
int subtract(int a, int b) // * Recursive subtraction of two integers
{
    if (b == 0)
        return a;
    return subtract((a ^ b), ((~a) & b) << 1);
}
int Subtract(int x, int y) // * Iterative subtraction of two integers
{
    while (y != 0)
    {
        int borrow = (~x) & y;
        x = x ^ y;
        y = borrow << 1;
    }
    return x;
}
// Russian Peasant using bitwise operator
int multiply(int a, int b) // * Multiplication function without using "*"
{
    int res = 0;
    while (b)
    {
        if (b & 1)
        {
            res = res + a;
        }
        a = a << 1;
        b = b >> 1;
    }
    return res;
}
int divide(int a, int b)
{
    int sign = ((a < 0) ^ (b < 0)) ? -1 : 1;
    a = abs(a);
    b = abs(b);
    int q = 0, tmp = 0;
    for (int i = 31; i >= 0; --i)
    {
        if (tmp + (b << i) <= a)
        {
            tmp += (b << i);
            q |= (1LL << i);
        }
    }
    return sign * q;
}
int bitcount(int n) // * Recursive function to check number of set bits of an integer
{
    if (n < 2)
        return n;
    return (n & 1) + bitcount(n >> 1);
}
bool ispowerof2(int n) // * check if a number is a power of 2
{
    return (__builtin_popcountll(n) == 1);
}
int gcd(int a, int b) // * Computes gcd using Euclid's algorithm
{
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
int lcm(int a, int b) // * Computes lcm of two numbers.
{
    return (a / gcd(a, b)) * b;
}
int binpow(int a, int b) // * Recursive power function
{
    if (b == 0)
        return a;
    int res = binpow(a, b / 2);
    if (b % 2)
        return res * res * a;
    else
        return res * res;
}
int pow(int a, int b) // * Iterative power function
{
    int res = 1;
    while (b)
    {
        if (b & 1)
            res = res * a;
        a = a * a;
        b >>= 1;
    }
    return res;
}
int modpow(int a, int b, int m) // *  Modular Exponentiation Iterative
{
    int res = 1;
    while (b)
    {
        if (b & 1)
            res = (res * a) % m;
        a = (a * a) % m;
        b >>= 1;
    }
    return res;
}
bool isprime(int x) // * Check if a number is prime or not.
{
    if (x < 2)
        return false;
    if (x < 4)
        return true;
    if (!(x & 1))
        return false;
    for (int i = 3; i * i <= x; i += 2)
        if (x % i == 0)
            return false;
    return true;
}

const int MOD = 1e9 + 7;
const int MXX = 1e5 + 69;
int fact[MXX], invfact[MXX];
int modinv(int k) // * Inverse Mod Function
{
    return modpow(k, MOD - 2, MOD);
}
void combinatorics()
{
    fact[0] = fact[1] = 1;
    for (int i = 2; i < MXX; i++)
    {
        fact[i] = fact[i - 1] * i;
        fact[i] %= MOD;
    }

    invfact[MXX - 1] = modinv(fact[MXX - 1]);
    for (int i = MXX - 2; i >= 0; i--)
    {
        invfact[i] = invfact[i + 1] * (i + 1);
        invfact[i] %= MOD;
    }
}
int nCr(int x, int y) // ~ nCr = ( n! / ( (n-r)! * r! ) )
{
    if (y > x)
        return 0;
    int num = fact[x];
    num *= invfact[y];
    num %= MOD;
    num *= invfact[x - y];
    num %= MOD;
    return num;
}
// transforms a string into lower case
string lwr(string s)
{
    transform(s.begin(), s.end(), s.begin(), ::tolower);
    return s;
}
// converts a string into uppercase
string upr(string s)
{
    transform(s.begin(), s.end(), s.begin(), ::toupper);
    return s;
}
// function to factorize a given number
vector<int> factorize(int n)
{
    vector<int> v;
    for (int i = 1; i * i <= n; i++)
    {
        if (n % i == 0)
        {
            v.push_back(i);
            if (i * i != n)
            {
                v.push_back(n / i);
            }
        }
    }
    sort(v.begin(), v.end());
    return v;
}
// Implementation of Disjoint Set Union
// using path compression and union by size.
// ! Grows very slowly - inverse ackermann function
// Link to dsu : https://cp-algorithms.com/data_structures/disjoint_set_union.html
class DSU
{
public:
    vector<int> par, sz;
    // Constructor for initializing
    DSU(int n)
    {
        n = n + 2;
        par.resize(n);
        sz.resize(n);
        for (int i = 0; i < n; i++)
            par[i] = i, sz[i] = 1;
    }
    // Returns the main parent/representative of the set
    int find(int x)
    {
        if (x == par[x])
            return par[x];
        else
            return (par[x] = find(par[x])); // Path Compression Optimization
        //  first find the representative of the set (root vertex), and the in the process of stack unwinding,
        // the visited nodes are attached directly to the representative.
    }
    // Unite two sets
    void Unite(int x, int y) // Union by Size
    {
        x = find(x);
        y = find(y);
        if (x == y)
            return;
        if (sz[x] < sz[y])
            swap(x, y);
        sz[x] += sz[y];
        par[y] = x;
    }
    // Check if 2 elements are in the same component
    bool Same(int x, int y)
    {
        return find(x) == find(y);
    }
    // returns the size of component in which element x belongs
    int size(int x)
    {
        return sz[find(x)];
    }
};
// Stack is LIFO (Last in First Out)
// Linked List based implementation of stacks
// It is better tham the implementation using arrays.
// Because it is dynamic
// In the main function, call it as StackNode sn; StackNode *root = NULL; root = all operations.
class StackNode
{
public:
    int data;
    StackNode *next;
    // Creates a new node to push onto the stack
    StackNode *CreateNode(int val)
    {
        StackNode *snw = new StackNode();
        snw->data = val;
        snw->next = NULL;
    }
    // Checks if the stack is empty
    int isEmpty(StackNode *root)
    {
        return (!root);
    }
    // Pushes a new-node onto the stack
    StackNode *push(StackNode *root, int val)
    {
        StackNode *nn = CreateNode(val);
        nn->next = root;
        root = nn;
        return root;
    }
    // remove the topmost element from the stack.
    StackNode *pop(StackNode *root)
    {
        if (isEmpty(root))
            return NULL;
        StackNode *tmp = root;
        (root) = (root)->next;
        int popped = tmp->data;
        free(tmp);
        return root;
    }
    // Returns the topmost element of the stack.
    int peek(StackNode *root)
    {
        if (isEmpty(root))
            return -2e9;
        return root->data;
    }
    // Returns the size of the stack
    int size(StackNode *root)
    {
        StackNode *a = root;
        int ans = 0;
        while (a != NULL)
        {
            a = a->next;
            ans++;
        }
        return ans;
    }
};
// Node representing a node of a Queue
class QNode
{
public:
    int data;
    QNode *next;
    QNode(int val)
    {
        data = val;
        next = NULL;
    }
};
// Class for operations on a Queue
// Queue is LIFO Last in First Out
class Queue
{
public:
    QNode *front;
    QNode *rear;
    Queue()
    {
        front = rear = NULL;
    }
    // Adding an element
    void EnQueue(int x)
    {
        QNode *tmp = new QNode(x);
        if (rear == NULL)
        {
            front = rear = tmp;
            return;
        }
        rear->next = tmp;
        rear = tmp;
    }
    // Removing an element
    void DeQueue()
    {
        if (front == NULL)
            return;
        QNode *tmp = front;
        front = front->next;
        if (front == NULL)
            rear = NULL;
        delete (tmp);
    }
    // To access the first element of the Queue
    int Front()
    {
        return front->data;
    }
    // To access the last element of the Queue
    int Back()
    {
        return rear->data;
    }
    // Check if the Queue is Empty
    bool isEmpty()
    {
        return front == rear and front == NULL;
    }
    // Prints the elements of the Queue
    void displayQueue()
    {
        QNode *a = front;
        while (a != NULL)
        {
            cout << (a->data) << " ";
            a = a->next;
        }
        cout << endl;
    }
};
// Function to print a vector
template <typename T>
void prev(vector<T> &v)
{
    for (auto t : v)
        cout << t << " ";
    cout << endl;
}
// Function to print a vector and its size too
template <typename T>
void prevs(vector<T> &v)
{
    cout << v.size() << endl;
    for (auto t : v)
        cout << t << " ";
    cout << endl;
}
// Function to print an array
void prar(int a[], int n, int x)
{
    for (int i = 0 + x; i < n + x; i++)
        cout << a[i] << " ";
    cout << endl;
}
template <typename T>
std::pair<bool, int> findInVector(const std::vector<T> &vecOfElements, const T &element)
{
    std::pair<bool, int> result;
    auto it = std::find(vecOfElements.begin(), vecOfElements.end(), element);
    if (it != vecOfElements.end())
    {
        result.second = distance(vecOfElements.begin(), it);
        result.first = true;
    }
    else
    {
        result.first = false;
        result.second = -1;
    }
    return result;
}
// function to check if a character is a vowel.
bool isvowel(char ch)
{
    string s = "aeiouAEIOU";
    for (char c : s)
        if (c == ch)
            return true;
    return false;
}
const int infms = 2e9;
int inversions = 0;
void Merge(int a[], int start, int mid, int end)
{
    int n1 = mid - start + 1;
    int n2 = end - mid;
    int left[n1 + 2];
    int right[n2 + 2];
    left[n1 + 1] = infms;
    right[n2 + 1] = infms;

    for (int i = 1; i <= n1; i++)
        left[i] = a[start + i - 1];

    for (int i = 1; i <= n2; i++)
        right[i] = a[mid + i];

    int x = 1, y = 1;
    for (int k = start; k <= end; k++)
        if (left[x] <= right[y])
        {
            a[k] = left[x];
            x++;
        }
        else
        {
            inversions += (1 + n1 - x);
            a[k] = right[y];
            y++;
        }
}
// Merge Sort algorithm
void MergeSort(int a[], int start, int end)
{
    if (start < end)
    {
        int mid = (start + end) / 2;
        MergeSort(a, start, mid);
        MergeSort(a, mid + 1, end);
        Merge(a, start, mid, end);
    }
}
// Recursive function to check if string is a palindrome
bool ispalindrome(string s)
{
    int n = s.length();
    if (n <= 1)
        return true;
    else if (n == 2 && s[1] == s[0])
        return true;
    else if (n == 2 && s[0] != s[1])
        return false;
    else if (s[0] != s[n - 1])
        return false;
    else
        return ispalindrome(s.substr(1, n - 2));
}
// function to check if string is a palindrome using STL
bool palindrome(string s)
{
    string t = s;
    reverse(all(t));
    return (t == s);
}
// iterative function to check if a string is a palindrome
bool checkpalindrome(string s)
{
    for (int i = 0; i <= s.length(); i++)
        if (s[i] != s[s.length() - 1 - i])
            return false;
    return true;
}
bool sortbysec(const pair<int, int> &a, const pair<int, int> &b)
{
    return (a.second < b.second);
}
// Dijkstra algorithm for Sparse Graph.
// ! single source shortest path algorithm for a graph with non negative edges.
// Implementation using Priority_queue
// ! Priority Queue is based on heaps.
// Therefore, it has a smaller hidden constant factor
//  but also has a drawback: it doesn't support the operation of removing an element.
// ? Link : https://cp-algorithms.com/graph/dijkstra_sparse.html
const int NN = 1e5 + 5;
vector<pair<int, int>> adj[NN];
vi d, p;
void dijkstra(int s, vector<int> &d, vector<int> &p)
{
    int n = NN;
    d.assign(n, inf);
    p.assign(n, -1);
    d[s] = 0; // distance of node from itself is 0.
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
    q.push({0, s}); // pushing the distance of node and node to the priority_queue
    while (!q.empty())
    {
        int v = q.top().second;  // the node
        int d_v = q.top().first; // the distance of the node from the source
        q.pop();
        if (d_v != d[v])
            continue; // we have found a shorter distance.
        // we can't delete the pii so we continue to next pii
        for (auto edge : adj[v])
        {
            int to = edge.first;
            int len = edge.second;
            if (d[v] + len < d[to])
            {
                d[to] = d[v] + len;
                p[to] = v;
                q.push({d[to], to});
            }
        }
    }
}
void path(vi &v, int d)
{
    if (p[d] != -1)
        path(v, p[d]);
    v.pb(d);
}
int addm(int a, int b)
{
    return ((a % mod) + (b % mod) + mod) % mod;
}
int subm(int a, int b)
{
    return ((a % mod) - (b % mod) + 2 * mod) % mod;
}
int mulm(int a, int b)
{
    return ((a % mod) * (b % mod) + mod) % mod;
}
int C(int n, int r)
{
    if (r > n - r)
        r = n - r; // because C(n, r) == C(n, n - r)
    int ans = 1;
    int i;
    for (i = 1; i <= r; i++)
    {
        ans *= n - r + i;
        ans /= i;
    }
    return ans;
}
void dream();
auto clk = clock();
int32_t main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    srand(chrono::high_resolution_clock::now().time_since_epoch().count());
    cout << setprecision(8);
    // ! while( (double)clock() / CLOCKS_PER_SEC < 0.95 ) // can be used in special cases
    // #ifndef ONLINE_JUDGE // Comment this if the question demands input-output through a file
    // freopen("input.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    // #endif
    // !  combinatorics(); // Take care of MOD
    int TESTCASES = 1;
    // cin >> TESTCASES;
    for (int i = 1; i <= TESTCASES; i++)
        dream();

#ifndef ONLINE_JUDGE
    cout << endl
         << "Time elapsed: " << (double)(clock() - clk) / CLOCKS_PER_SEC << endl
         << endl;
#endif
    return 0;
}

/* Comments  */
// * green
// ~ blue
// @ purple
// # orange
// $ lime
// ! red

vi g[101010];
bool vis[101010];
bool ok = false;
int edges = 0;

void dfs(int s, int p)
{
    if (vis[s])
    {
        ok = false;
        return;
    }
    vis[s] = true;
    for (auto t : g[s])
    {
        if (t != p)
        {
            dfs(t, s);
        }
    }
}

void dream()
{
    int n, m;
    cin >> n >> m;
    set<int> s;
    fr(i, m)
    {
        int u, v;
        cin >> u >> v;
        g[u].pb(v);
        g[v].pb(u);
    }

    int ans = 0;
    fr(i, n)
    {
        if (!vis[i])
        {
            ok = true;
            dfs(i, -1);
            if (ok)
                ++ans;
        }
    }

    cout << ans << endl;

    // ? you should actually read the stuff at the bottom
}
/*
    ! stuff you should look for
        * int overflow, array bounds
        * special cases (n=1)?
        * boundary cases
        * do something instead of nothing and stay organized.
        # BELIEVE in yourself.
*/
/*
? Some basic stuff that you should learn:

        ? Sets : Unique element container.
            ! set<int,greater<int> > s; // to order the set in descending order
            * To check if an element is in a set : s.count(x)
            ! Another method to check if an element exists in a set :if(s.find(x)!=s.end()){ // condition  }
            * Value of First Element of Set : *(s.begin())
            * Value of Last Element of Set : *(--s.end())
            ! To erase an element by value: s.erase(x);
            * begin() - returns an iterator to first element of set. The value of the element can be accessed using *(s.begin())
            * end() - Returns an iterator to the theoretical element that follows last element in the set.
            * size() - Returns the number of elements in the set.
            * max_size() - Returns the maximum number of elements that the set can hold.
            * empty() - Returns whether the set is empty.
            ! find(x) - Returns an iterator to the element ‘x’ in the set if found, else returns the iterator to end.
            * erase(x)– Removes the value ‘x’ from the set. It erases an element by value
            * count(x) - Returns 1 or 0 based on the element ‘x’ is present in the set or not. It's the best way to check for the presence of an element.
            * lower_bound(x) – Returns an iterator to the first element that is equivalent to ‘x’ or definitely will not go before the element ‘x’ in the set.
              lower_bound can also be thought as the smallest element greater than or equal to x
            * Return reverse iterator to reverse beginning: (s.rbegin())
            * Set to be sorted in decreasing order: set<int, greater<int> >
            * emplace() : If the function successfully inserts the element (because no
                    equivalent element existed already in the set), the function returns a
                    pair of an iterator to the newly inserted element and a value of true.
            * const bool is_in = s.find(x) != s.end(); check if an element is in the set.
            ! myset.erase(x) #directly by value. logarithmic complexity
            ! myset.erase(iteratortoanelement,s.end())
            * for_each(all(s),do_something);
            ! set<int> :: iterator it = myset.find(60);

        ? Vectors
            @ Erase elemnents by value rather than position
            # vec.erase(std::remove(vec.begin(), vec.end(), 8), vec.end());
            *
            @ Erase duplicates in a sorted array
            # v.erase(unique(v.begin(), v.end()), v.end());
            *
            @ Erase elements by position
            # vec.erase(vec.begin() + 1);
            vector<int> v; v.resize(n,0); // resizes the vector and initializes it too.
            front(), back(), push_back(), pop_back()
            * begin() - Returns an iterator pointing to the first element in the vector
            * end() - Returns an iterator pointing to the theoretical element that follows the last element in the vector
            * rbegin() - Returns a reverse iterator pointing to the last element in the vector (reverse beginning).
            * rend() - Returns a reverse iterator pointing to the theoretical element preceding the first element in the vector
            * cbegin(),cend(),crbegin(),crend()
            * size() - Returns the number of elements in the vector.
            * max_size() -  Returns the maximum number of elements that the vector can hold.
            * capacity() - Returns the size of the storage space currently allocated to the vector expressed as number of elements.
            * resize() - Resizes the container so that it contains ‘n’ elements.
            * empty() - Returns whether the container is empty.
            * shrink_to_fit() - Reduces the capacity of the container to fit its size and destroys all elements beyond the capacity.
            * reserve() - Requests that the vector capacity be at least enough to contain n elements.
            * [i] - Returns a reference to the element at position ‘i’ in the vector
            * at(i) - Returns a reference to the element at position ‘i’ in the vector
            # front() - Returns a reference to the first element in the vector
            # back() - Returns a reference to the last element in the vector
            * data() - Returns a direct pointer to the memory array used internally by the vector to store its owned elements.
            * assign() - It assigns new value to the vector elements by replacing old ones
            * push_back() - It push the elements into a vector from the back
            # pop_back() - It is used to pop or remove elements from a vector from the back.
            ! insert() - It inserts new elements before the element at the specified position
            * erase() - It is used to remove elements from a container from the specified position or range
            * swap() - It is used to swap the contents of one vector with another vector of same type. Sizes may differ.
            * clear() - It is used to remove all the elements of the vector container
            * emplace() - It extends the container by inserting new element at position
            * emplace_back() - It is used to insert a new element into the vector container, the new element is added to the end of the vector
            # for (auto it = myvector.begin(); it != myvector.end(); ++it)  // normal iterator
            # for (auto t:v)

        ? Queue
            * empty() - Returns whether the queue is empty.
            * size() - Returns the size of the queue.
            * emplace() - Insert a new element into the queue container, the new element is added to the end of the queue.
            * front() - front() function returns a reference to the first element of the queue.
            * back() - returns a reference to the last element of the queue.
            * push(x) - adds the element ‘x’ at the end of the queue
            * pop() - deletes the first element of the queue

        ? Priority_Queue
            ! priority_queue <int, vector<int>, greater<int>> pq; // to make a priority queue in descending order
            * empty() - returns whether the queue is empty.
            * size() -  returns the size of the queue.
            # top() -  Returns a reference to the top most element of the queue
            * push(x) - adds the element ‘x’ at the end of the queue.
            * pop() -  deletes the first element of the queue.
            * swap() -  swap the contents of one priority queue with another priority queue of same type and size.
            * emplace() - insert a new element into the priority queue container, the new element is added to the top of the priority queue.

        ? Deque
            Double ended queues are sequence containers with the feature of expansion and contraction on both the ends.
            They are similar to vectors, but are more efficient in case of insertion and deletion of elements.
            Unlike vectors, contiguous storage allocation may not be guaranteed.
            * insert()
            * rbegin()
            * rend()
            * assign()
            * resize()
            * push_front()
            * push_back()
            * pop_front()
            * pop_back()
            * front()
            * back()
*/