stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

const int boss=1e5;

int n,m,vis[boss+10];

vector<int> lj[boss+10];

int dfs(int u,int fa)

{

if (lj[u].size()>2) return u;

for (int i:lj[u]) if (i!=fa) return dfs(i,u);

return u;

}

int main()

{

int i,u,v;

scanf("%d",&n);

for (i=1;i<n;i++) scanf("%d%d",&u,&v),u++,v++,lj[u].push_back(v),lj[v].push_back(u);

for (i=1;i<=n;i++) if (lj[i].size()==1) vis[dfs(i,0)]=1,m++;

for (i=1;i<=n;i++) if (vis[i]) m--;

printf("%d",max(m,1));

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;



const int maxn=100010;

int du[maxn];

int n,root;

struct Edge

{

	int v,next;

}	e[maxn<<1];

int g[maxn],tot;

int fa[maxn];

bool has[maxn];

int ans;

void addedge(int x,int y)

{

	tot++;

	e[tot].v=y;

	e[tot].next=g[x];

	g[x]=tot;

}

void dfs(int t)

{

	int son=du[t];

	if (fa[t]!=0)	son--;

	for (int i=g[t];i;i=e[i].next)

	if (e[i].v!=fa[t])

	{

		fa[e[i].v]=t;

		dfs(e[i].v);

		if (has[e[i].v])	son--,has[t]=true;

	}

	if (son>1)

	{

		ans+=son-1;

		has[t]=true;

	}

}

int main()

{

	scanf("%d",&n);

	for (int i=1;i<n;i++)

	{

		int x,y;

		scanf("%d%d",&x,&y);

		x++;y++;

		addedge(x,y);

		addedge(y,x);

		du[x]++;

		du[y]++;

		if (du[x]>2)	root=x;

	}

	if (!root)

	{

		printf("1\n");

		return 0;

	}

	ans=0;

	fa[root]=0;

	dfs(root);

	printf("%d\n",ans);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

int dp[100005], n;

vector<int> c[100005];

void dfs(int x, int pa){

	int add = 0;

	for(int i = 0; i < c[x].size(); ++i){

		int v = c[x][i];

		if(v != pa){

			dfs(v, x);

			dp[x] += dp[v];

			if(dp[v] == 0) add++;

		}

	}

	dp[x] += max(add - 1, 0);

}

int main(){

	cin >> n;

	for(int i = 1; i <= n - 1; ++i){

		int x, y;

		cin >> x >> y;

		c[x].push_back(y);

		c[y].push_back(x);

	}

	int maxi = 0;

	for(int i = 0; i < n; ++i){

		if(c[i].size() > c[maxi].size()) maxi = i;

	}

	if(c[maxi].size() < 2){

		cout << 1;

		return 0;

	}

	dfs(maxi, -1);

	cout << dp[maxi] << endl;

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<cstdio>

const int N=1e5+5;

int n,cnt,head[N],nxt[N<<1],to[N<<1],deg[N];

void init() {

    for(int i=0;i<n;i++) head[i]=-1,deg[i]=0;cnt=0;

}

void addEdge(int u,int v) {

    nxt[cnt]=head[u];to[cnt]=v;head[u]=cnt++;

}

int dfs(int u,int fa) {

    int ans=0;bool f=false;

    for(int i=head[u];~i;i=nxt[i]) {

        int v=to[i];if(v==fa) continue;

        int tmp=dfs(v,u);

        ans+=tmp?tmp:f;

        f=f||!tmp;

    }

    return ans;

}

int main() {

    scanf("%d",&n);init();int u,v;

    for(int i=1;i<n;i++) scanf("%d%d",&u,&v),addEdge(u,v),addEdge(v,u),deg[v]++,deg[u]++;

    int root=-1;

    for(int i=0;i<n;i++) if(deg[i]>2) root=i;

    printf("%d\n",root==-1?1:dfs(root,-1));

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

const int boss=1e5;

int n,m,vis[boss+10];

vector<int> lj[boss+10];

int dfs(int u,int fa)

{

if (lj[u].size()>2) return u;

for (int i:lj[u]) if (i!=fa) return dfs(i,u);

return u;

}

int main()

{

int i,u,v;

scanf("%d",&n);

for (i=1;i<n;i++) scanf("%d%d",&u,&v),u++,v++,lj[u].push_back(v),lj[v].push_back(u);

for (i=1;i<=n;i++) if (lj[i].size()==1) vis[dfs(i,0)]=1,m++;

for (i=1;i<=n;i++) if (vis[i]) m--;

printf("%d",max(m,1));

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<cstdio>

const int N=1e5+5;

int n,cnt,head[N],nxt[N<<1],to[N<<1],deg[N];

void init() {

    for(int i=0;i<n;i++) head[i]=-1,deg[i]=0;cnt=0;

}

void addEdge(int u,int v) {

    nxt[cnt]=head[u];to[cnt]=v;head[u]=cnt++;

}

int dfs(int u,int fa) {

    int ans=0;bool f=false;

    for(int i=head[u];~i;i=nxt[i]) {

        int v=to[i];if(v==fa) continue;

        int tmp=dfs(v,u);

        ans+=tmp?tmp:f;

        f=f||!tmp;

    }

    return ans;

}

int main() {

    scanf("%d",&n);init();int u,v;

    for(int i=1;i<n;i++) scanf("%d%d",&u,&v),addEdge(u,v),addEdge(v,u),deg[v]++,deg[u]++;

    int root=-1;

    for(int i=0;i<n;i++) if(deg[i]>2) root=i;

    printf("%d\n",root==-1?1:dfs(root,-1));

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



const int MAXN = 101010;



int n, m;



int ind[MAXN];



class Road {

public:

	int t, next;

}e[MAXN * 2];

int p[MAXN];

int z = -1;



int vis[MAXN];



void add(int u, int v) {

	++z;

	e[z].t = v;

	e[z].next = p[u];

	p[u] = z;

}



int cnt = 0;



bool dfs(int u, int fa) {

	//cout<<u<<" "<<fa<<endl;

	int cnt1 = 0, cnt2 = 0;

	for(int tmp = p[u]; tmp != -1; tmp = e[tmp].next) {

		if(e[tmp].t != fa) {

			cnt1++;

			cnt2 += dfs(e[tmp].t, u);

		}

	}

	if(cnt1 - 1 > cnt2) {

		cnt += cnt1 - 1 - cnt2;

		return true;

	}

	return cnt2;

}



int main() {

	memset(p, -1, sizeof(p));

	

	scanf("%d", &n);

	int u, v;

	for(int i = 1; i < n; ++i) {

		scanf("%d%d", &u, &v);

		ind[u]++, ind[v]++;

		add(u, v);

		add(v, u);

	}

	int mx = 0, mxp;

	for(int i = 0; i < n; ++i)

		if(ind[i] > mx) {

			mx = ind[i];

			mxp = i;

		}

	if(mx <= 2) {

		puts("1");

		return 0;

	}

	dfs(mxp, -1);

	printf("%d\n", cnt);



	return 0;

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<cstdio>

const int N=1e5+5;

int n,cnt,head[N],nxt[N<<1],to[N<<1],deg[N];

void init() {

    for(int i=0;i<n;i++) head[i]=-1,deg[i]=0;cnt=0;

}

void addEdge(int u,int v) {

    nxt[cnt]=head[u];to[cnt]=v;head[u]=cnt++;

}

int dfs(int u,int fa) {

    int ans=0;bool f=false;

    for(int i=head[u];~i;i=nxt[i]) {

        int v=to[i];if(v==fa) continue;

        int tmp=dfs(v,u);

        ans+=tmp?tmp:f;

        f=f||!tmp;

    }

    return ans;

}

int main() {

    scanf("%d",&n);init();int u,v;

    for(int i=1;i<n;i++) scanf("%d%d",&u,&v),addEdge(u,v),addEdge(v,u),deg[v]++,deg[u]++;

    int root=-1;

    for(int i=0;i<n;i++) if(deg[i]>2) root=i;

    printf("%d\n",root==-1?1:dfs(root,-1));

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <cstdio>

#include <cstdlib>

#include <algorithm>

#include <vector>



const int maxn = 1e5 + 20;



int n, m;

std::vector<int> G[maxn];

bool vis[maxn];



int dfs(int u,int fa)

{

	if(G[u].size() > 2) return u;

	

	for(int i = 0; i < G[u].size(); i++)

	{

		int v = G[u][i];

		

		if(v != fa) return dfs(v, u);

	}

	

	return u;

}

int main()

{

	scanf("%d", &n);

	for(int i = 1, u, v; i < n; i++)

	{

		scanf("%d%d", &u, &v);

		u++, v++;

		G[u].push_back(v);

		G[v].push_back(u);

	}

	

	for(int i = 1; i <= n; i++)

		if(G[i].size() == 1) vis[dfs(i, 0)] = true, m++;

	

	for(int i = 1; i <= n; i++)

		if(vis[i]) m--;

	

	m = std::max(m, 1);

	printf("%d\n", m);	

	return 0;

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<cstdio>

const int N=1e5+5;

int n,cnt,head[N],nxt[N<<1],to[N<<1],deg[N];

void init() {

    for(int i=0;i<n;i++) head[i]=-1,deg[i]=0;cnt=0;

}

void addEdge(int u,int v) {

    nxt[cnt]=head[u];to[cnt]=v;head[u]=cnt++;

}

int dfs(int u,int fa) {

    int ans=0;bool f=false;

    for(int i=head[u];~i;i=nxt[i]) {

        int v=to[i];if(v==fa) continue;

        int tmp=dfs(v,u);

        ans+=tmp?tmp:f;

        f=f||!tmp;

    }

    return ans;

}

int main() {

    scanf("%d",&n);init();int u,v;

    for(int i=1;i<n;i++) scanf("%d%d",&u,&v),addEdge(u,v),addEdge(v,u),deg[v]++,deg[u]++;

    int root=-1;

    for(int i=0;i<n;i++) if(deg[i]>2) root=i;

    printf("%d\n",root==-1?1:dfs(root,-1));

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<vector>

#include<algorithm>

#define MAXN 200006

using namespace std;

int d[MAXN],n,a,b;

vector<int> road[MAXN];

void DFS(int x,int fa)

{

	int ok=0;

	for(int i=0;i<(int)road[x].size();i++)

	{

		int nex=road[x][i];

		if(nex==fa) continue;

		DFS(nex,x);

		if(d[nex]==0)

		{

			if(ok==0) ok=1;

			else d[x]++;

		}

		else d[x]+=d[nex];

	}

}

int main()

{

	scanf("%d",&n);

	for(int i=1;i<n;i++)

	{

		scanf("%d%d",&a,&b);

		a++;

		b++;

		road[a].push_back(b);

		road[b].push_back(a);

	}

	int st=0;

	for(int i=1;i<=n;i++)

	{

		if(road[i].size()>=3)

		{

			st=i;

			break;

		}

	}

	if(st==0) printf("1");

	else 

	{

		DFS(st,0);

		printf("%d",d[st]);

	}

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<cstdio>

const int N=1e5+5;

int n,cnt,head[N],nxt[N<<1],to[N<<1],deg[N];

void init() {

    for(int i=0;i<n;i++) head[i]=-1,deg[i]=0;cnt=0;

}

void addEdge(int u,int v) {

    nxt[cnt]=head[u];to[cnt]=v;head[u]=cnt++;

}

int dfs(int u,int fa) {

    int ans=0;bool f=false;

    for(int i=head[u];~i;i=nxt[i]) {

        int v=to[i];if(v==fa) continue;

        int tmp=dfs(v,u);

        ans+=tmp?tmp:f;

        f=f||!tmp;

    }

    return ans;

}

int main() {

    scanf("%d",&n);init();int u,v;

    for(int i=1;i<n;i++) scanf("%d%d",&u,&v),addEdge(u,v),addEdge(v,u),deg[v]++,deg[u]++;

    int root=-1;

    for(int i=0;i<n;i++) if(deg[i]>2) root=i;

    printf("%d\n",root==-1?1:dfs(root,-1));

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
//dfs版 

#include<iostream>

#include<cctype>

#include<queue>

#include<cstdio>

#include<cmath>

#include<sstream>

#include<string>

#include<algorithm>

#include<cstring>

#include<vector>

#include<ctime>

#include<cstdlib>

#include<map>

#include<utility>

#include<iomanip>

#include<set>

#include<stack>

#define lowbit(i) ((i)&(-i))

using namespace std;

typedef long long ll;typedef pair<int,int> pii;

typedef pair<ll,ll> pll;typedef vector<string> vss;

typedef vector<int> vii;typedef vector<pii> vpi;

typedef vector<ll> vll;typedef vector<pll> vpl;typedef long double ld;

typedef unsigned long long ul;typedef queue<int> qii;typedef queue<pii> qpi;

int n,x,y,dp[100005],res,t;

vii v[100005];

int mx=0,deg[1000005];

qii q;

int main()

{

// 	freopen("","r",stdin);

// 	freopen("","w",stdout);

	cin>>n;

	for(int i=1;i<n;i++){

		cin>>x>>y;

		v[x].push_back(y);

		v[y].push_back(x);

		deg[x]++;

		deg[y]++;

	}

	for(int i=0;i<n;i++){

		if(v[i].size()>mx)

			mx=v[i].size();

	}

	if(mx<=2){

		puts("1");

		return 0;

	}

	for(int i=0;i<n;i++){

		if(deg[i]==1) q.push(i);

	}

	while(!q.empty()){

		int p=q.front(),to=-1;q.pop();

		for(int i=0;i<v[p].size();i++){

			to=v[p][i];

			if(deg[to]!=1) break;

		}

		if(deg[to]==2){

			deg[to]=1;

			q.push(to);

		}

	}

	for(int i=0;i<n;i++){

		if(deg[i]==1) continue;

		t=0;

		for(int j=0;j<v[i].size();j++){

			int to=v[i][j];

			if(deg[to]==1) t++;

		}

		res+=max(0,t-1);

	}

	cout<<res<<'\n';

	return 0;

}

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#include<algorithm>

#define MAXN 100000

struct node

{

	int to;

	node *next;

}edge[MAXN*2+5];

node *ncnt=&edge[0],*Adj[MAXN+5];

int d[MAXN+5],root=MAXN+5,dp[MAXN+5];

bool vis[MAXN+5];

int n;

void AddEdge(int u,int v)

{

	node *p=++ncnt;

	p->to=v;

	p->next=Adj[u];

	Adj[u]=p;

	

	node *q=++ncnt;

	q->to=u;

	q->next=Adj[v];

	Adj[v]=q;

}

void dfs(int u)

{

	vis[u]=true;

	int chnum=0,nothave=0;

	for(node *p=Adj[u];p!=NULL;p=p->next)

	{

		int v=p->to;

		if(vis[v]==false)

		{

			chnum++;

			dfs(v);

			dp[u]+=dp[v];

			if(dp[v]==0)

				nothave++;

		}

	}

	if(nothave>=2)

		dp[u]+=nothave-1;

}

int main()

{

	scanf("%d",&n);

	int x,y;

	for(int i=1;i<n;i++)

	{

		scanf("%d %d",&x,&y);

		AddEdge(x,y);

		d[x]++,d[y]++;

	}

	for(int i=0;i<n;i++)

	{

		if(d[i]>=3)

		{

			root=i;

			break;

		}

	}

	if(root>MAXN)

	{

		printf("1\n");

		return 0;

	}

	dfs(root);

	printf("%d\n",dp[root]);

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <vector>

const int Maxn=1e5+5;

#define rep(i,n) for (int i=0;i<n;++i)

#define int long long

int n,mx;

std::vector <int> v[Maxn];

int dp[Maxn];

void dfs(int k,int p=-1)

{

	int s=0;

	int ss=0;

	std::vector <int> t;

	for (auto &x:v[k])

	{

		if (x==p)

		{

			continue;

		}

		ss++;

		t.push_back(x);

		dfs(x,k);

		if (dp[x])

		{

			s++;

		}

		dp[k]+=dp[x];

	}

	dp[k]+=std::max(ss-s-1,0ll);

}

signed main()

{

	std::cin>>n;

	for (int i=1;i<n;++i)

	{

		int x,y;

		std::cin>>x>>y;

		v[x].push_back(y);

		v[y].push_back(x);

	}

	rep(i,n)

	{

		if (v[i].size()>v[mx].size())

		{

			mx=i;

		}

	}

	dfs(mx);

	std::cout<<std::max(1ll,dp[mx])<<std::endl;

	return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define maxl 100010



using namespace std;



int n,ans,cnt;

int ehead[maxl];

int du[maxl];

struct ed

{

	int to,nxt;

}e[maxl<<1];

bool vis[maxl];



inline void add(int u,int v)

{

	e[++cnt].to=v;e[cnt].nxt=ehead[u];ehead[u]=cnt;

}



inline void prework()

{

	for(int i=1;i<=n;i++)

		vis[i]=false,ehead[i]=0,du[i]=0;

	int u,v;

	cnt=0;

	for(int i=1;i<n;i++)

	{

		scanf("%d%d",&u,&v);

		u++;v++;

		add(u,v);du[v]++;

		add(v,u);du[u]++;

	}

}



inline int dfs(int u,int fa)

{

	int v;

	for(int i=ehead[u];i;i=e[i].nxt)

	{

		v=e[i].to;

		if(v==fa) continue;

		if(du[v]>2)

			return v;

		else

			return dfs(v,u);

	}

}



inline void mainwork()

{

	bool flag=true;

	for(int i=1;i<=n;i++)

	if(du[i]>2)

		flag=false;

	if(flag)

	{

		ans=1;

		return;

	}

	ans=0;

	for(int i=1;i<=n;i++)

	if(du[i]==1)

		vis[dfs(i,0)]=true,ans++;

	for(int i=1;i<=n;i++)

	if(vis[i])

		ans--;

}



inline void print()

{

	printf("%d\n",ans);

}



int main()

{

	while(~scanf("%d",&n))

	{

		prework();

		mainwork();

		print();

	}

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5+100;

typedef long long LL;

int val[maxn],First[maxn],cnt,N,M,deg[maxn];

int tot,pre[maxn],rdeg[maxn];

int ans = 0;

struct node{

    int to,Next;

}Tree[maxn*2];

void init(){

    memset(First,-1,sizeof(First));

    cnt = 0;

}

void addedge(int from,int to){

    Tree[cnt].to = to;

    Tree[cnt].Next = First[from];

    First[from] = cnt++;

}

int dfs(int u,int fa){

    if(deg[u]==0)return 0;

    int shoud = deg[u] - 1;

    int bouns = 0;

    for(int i = First[u];i!=-1;i=Tree[i].Next){

        int to = Tree[i].to;

        if(to==fa)continue;

        deg[to]--;

        bouns+=dfs(to,u);

    }

    ans+=max(0,shoud-bouns);

    return bouns||(shoud-bouns);

}

int main(){

    init();

    scanf("%d",&N);

    for(int i = 0;i<N-1;i++){

        int a,b;

        scanf("%d%d",&a,&b);

        addedge(a,b);

        addedge(b,a);

        deg[a]++;

        deg[b]++;

    }

    int now = 0,max1 = 0;

    for(int i = 0;i<=N-1;i++){

            rdeg[i] = deg[i];

            if(deg[i]>max1){

                now = i;

                max1 = deg[i];

            }

    }

    dfs(now,-1);

    printf("%d\n",max(1,ans));

    return 0;

}

/*

7

0 1

0 2

1 3

1 4

1 5

2 6



*/


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define maxl 100010



using namespace std;



int n,ans,cnt;

int ehead[maxl];

int du[maxl];

struct ed

{

	int to,nxt;

}e[maxl<<1];

bool vis[maxl];



inline void add(int u,int v)

{

	e[++cnt].to=v;e[cnt].nxt=ehead[u];ehead[u]=cnt;

}



inline void prework()

{

	for(int i=1;i<=n;i++)

		vis[i]=false,ehead[i]=0,du[i]=0;

	int u,v;

	cnt=0;

	for(int i=1;i<n;i++)

	{

		scanf("%d%d",&u,&v);

		u++;v++;

		add(u,v);du[v]++;

		add(v,u);du[u]++;

	}

}



inline int dfs(int u,int fa)

{

	int v;

	for(int i=ehead[u];i;i=e[i].nxt)

	{

		v=e[i].to;

		if(v==fa) continue;

		if(du[v]>2)

			return v;

		else

			return dfs(v,u);

	}

}



inline void mainwork()

{

	bool flag=true;

	for(int i=1;i<=n;i++)

	if(du[i]>2)

		flag=false;

	if(flag)

	{

		ans=1;

		return;

	}

	ans=0;

	for(int i=1;i<=n;i++)

	if(du[i]==1)

		vis[dfs(i,0)]=true,ans++;

	for(int i=1;i<=n;i++)

	if(vis[i])

		ans--;

}



inline void print()

{

	printf("%d\n",ans);

}



int main()

{

	while(~scanf("%d",&n))

	{

		prework();

		mainwork();

		print();

	}

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

#include<vector>

#define SF scanf

#define PF printf

#define MAXN 100010

using namespace std;

vector<int> a[MAXN];

int n,root=-1;

int dfs(int x,int fa){

    int res=0;

    int flag=0;

    for(int i=0;i<a[x].size();i++){

        if(a[x][i]==fa)

            continue;

        int res1=dfs(a[x][i],x);

        if(res1==0&&flag==1)

            res++;

        if(res1==0&&flag==0)

            flag=1;

        res+=res1;

    }

    return res;

}

int main(){

    SF("%d",&n);

    int u,v;

    for(int i=1;i<n;i++){

        SF("%d%d",&u,&v);

        a[u].push_back(v);

        a[v].push_back(u);

    }

    for(int i=0;i<n;i++)

        if(a[i].size()>=3){

            root=i;

            break;

        }

    if(root==-1){

        PF("1");

        return 0;

    }

    PF("%d",dfs(root,-1));

}

// Optimized solution to the same problem (faster):
/*#pragma comment(linker, "/stack:200000000")

#pragma GCC optimize("Ofast")

#pragma target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")*/

#include<bits/stdc++.h>

#define ll long long

#define inf 1000000005

#define mod 1000000007

#define put putchar('\n')

#define F(i,a,b) for (int i=(a);i<=(b);i++)

#define D(i,a,b) for (int i=(a);i>=(b);i--)

#define go(i,t) for (int i=head[t];i;i=Next[i])

#define sqr(x) ((x)*(x))

#define re register

#define mp make_pair

#define fi first

#define se second

#define pa pair<int,int>

#define pb push_back

#define be begin()

#define en end()

#define ret return puts("-1"),0;

#define N 500055

//#define int ll

using namespace std;

inline char gc(){

    static char buf[100000],*p1=buf,*p2=buf;

    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;

}

#define gc getchar

inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}

int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}

inline void wr(int x){if (x<0) {putchar('-');wr(-x);return;}if(x>=10)wr(x/10);putchar(x%10+'0');}

inline void wrn(int x){wr(x);put;}inline void wri(int x){wr(x);putchar(' ');}

inline void wrn(int x,int y){wri(x);wrn(y);}inline void wrn(int a,int b,int c){wri(a);wrn(b,c);}

int n,m,fa[N],in1[N],ans,x,y;

int nedge,head[N*2],to[N*2],Next[N*2];

#define V to[i]

void add(int a,int b){

   Next[++nedge]=head[a];head[a]=nedge;to[nedge]=b;

}

int dfs(int x,int fa){

	int flag=0,p=0,sum=0;

	go(i,x){

		if (fa==V) continue;

		p=dfs(V,x);

		if (p==0&&flag==1) sum++;

		if (p==0&&flag==0) flag=1;

		sum+=p;

	}

	return sum;

} 

signed main(){

	n=read();

	F(i,1,n-1){

		x=read();y=read();

		add(x,y);add(y,x);in1[x]++;in1[y]++;

	}

	int pd=0;

	F(i,0,n-1){

		if (in1[i]>=3){

			ans=dfs(i,-1);pd=1;

			break;

		} 

	}

	if (!pd){

		wrn(1);return 0;

	}

//	ans=max(ans,1);

	wrn(ans);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<iostream>

#include<fstream>

#include<sstream>

#include<algorithm>

#include<cstdio>

#include<cassert>

#include<cmath>

#include<cstdlib>

#include<cstring>

#include<string>

#include<deque>

#include<queue>

#include<vector>

#include<list>

#include<map>

#include<set>

#include<bitset>

#include<stack>

#include<iomanip>

#include<utility>

#include<functional>

using namespace std;

int n,root,mr;

vector<int> edge[100005];

long long dp[100005];

void dfs(int dep,int prev)

{

	long long y=0;

	for(int i=0;i<edge[dep].size();i++)

	{

		int x=edge[dep][i];

		if(x!=prev)

		{

			dfs(x,dep);

			dp[dep]+=dp[x];

			if(dp[x]==0)

				y++;

		}

	}

	dp[dep]+=max((long long)0,y-1);

}

int main()

{

	cin>>n;

	for(int i=0;i<n-1;i++)

	{

		int a,b;

		cin>>a>>b;

		edge[a].push_back(b);

		edge[b].push_back(a);

	}

	for(int i=0;i<n;i++)

		if(edge[i].size()>mr)

		{

			root=i;

			mr=edge[i].size();

		}

	dfs(root,-1);

	if(dp[root]==0)

		cout<<1;

	else

		cout<<dp[root];

	return 0;

}


// Optimized solution to the same problem (faster):
#include<cmath>

#include<cstdio>

#include<algorithm>

using namespace std;

struct node{

	int ne,tow;

};

node pth[200000+10];

int mp[100000+10],szp;

int vis[100000+10];

int n;

int deg[100000+10];

int root=-1;

int son[100000+10];

int bro[100000+10];

int dp[100000+10];

int left[100000+10];

void addpath(int i,int j){

	++szp;

	pth[szp].ne=mp[i];

	pth[szp].tow=j;

	mp[i]=szp;

	deg[i]++;

}



void dfs1(int i,int j){

	if (vis[i]!=0) return;

	vis[i]=j;

	int po=mp[i];

	while (po!=-1){

		if (vis[pth[po].tow]==0){

			bro[pth[po].tow]=son[i];

			son[i]=pth[po].tow;

		}

		dfs1(pth[po].tow,j+1);

		po=pth[po].ne;

	}	

}

void dfs2(int i){

	int j=son[i];

	if (j==-1){

		left[i]=1;

		dp[i]=1;

		return;

	}

	while (j!=-1){

		dfs2(j);

		left[i]+=left[j];

		dp[i]+=dp[j];

		j=bro[j];

	}

	j=son[i];

	if (j!=-1&&bro[j]!=-1)

	while (j!=-1){

		if (dp[j]==1&&left[j]==1){

			dp[i]--;

			return;

		}

		j=bro[j];

	}



}





int main(){

	scanf("%d",&n);

	for (int f1=0;f1<n;f1++){

		mp[f1]=-1;

		vis[f1]=0;

	}

	

	for (int f1=1;f1<n;f1++){

		int i,j;

		scanf("%d%d",&i,&j);

		addpath(i,j);

		addpath(j,i);

		if (deg[i]>2)root=i;

		if (deg[j]>2)root=j;

	}

	if (root==-1){

		printf("1\n");

		return 0;

	}

	for (int f1=0;f1<n;f1++){

		son[f1]=-1;

		bro[f1]=-1;

		left[f1]=0;

		dp[f1]=0;

	}

	dfs1(root,1);

	dfs2(root);

	printf("%d\n",dp[root]);

	//for (int f1=0;f1<n;f1++)printf("%d ",dp[f1]);

}


// Fastest known solution for this problem: