Problem:
Score : 900 points

Problem Statement

We have a tree with N vertices.
The vertices are numbered 0 through N - 1, and the i-th edge (0 ≤ i < N - 1) comnnects Vertex a_i and b_i.
For each pair of vertices u and v (0 ≤ u, v < N), we define the distance d(u, v) as the number of edges in the path u-v.

It is expected that one of the vertices will be invaded by aliens from outer space.
Snuke wants to immediately identify that vertex when the invasion happens.
To do so, he has decided to install an antenna on some vertices.

First, he decides the number of antennas, K (1 ≤ K ≤ N).
Then, he chooses K different vertices, x_0, x_1, ..., x_{K - 1}, on which he installs Antenna 0, 1, ..., K - 1, respectively.
If Vertex v is invaded by aliens, Antenna k (0 ≤ k < K) will output the distance d(x_k, v).
Based on these K outputs, Snuke will identify the vertex that is invaded.
Thus, in order to identify the invaded vertex no matter which one is invaded, the following condition must hold:

For each vertex u (0 ≤ u < N), consider the vector (d(x_0, u), ..., d(x_{K - 1}, u)). These N vectors are distinct.

Find the minumum value of K, the number of antennas, when the condition is satisfied.

Constraints

2 ≤ N ≤ 10^5

0 ≤ a_i, b_i < N

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_0 b_0
a_1 b_1
:
a_{N - 2} b_{N - 2}

Output

Print the minumum value of K, the number of antennas, when the condition is satisfied.

Sample Input 1

5
0 1
0 2
0 3
3 4

Sample Output 1

2

For example, install an antenna on Vertex 1 and 3.
Then, the following five vectors are distinct:

(d(1, 0), d(3, 0)) = (1, 1)

(d(1, 1), d(3, 1)) = (0, 2)

(d(1, 2), d(3, 2)) = (2, 2)

(d(1, 3), d(3, 3)) = (2, 0)

(d(1, 4), d(3, 4)) = (3, 1)

Sample Input 2

2
0 1

Sample Output 2

1

For example, install an antenna on Vertex 0.

Sample Input 3

10
2 8
6 0
4 1
7 6
2 3
8 6
6 9
2 4
5 8

Sample Output 3

3

For example, install an antenna on Vertex 0, 4, 9.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
#ifndef ONLINE_JUDGE
	#include <boost/multiprecision/cpp_int.hpp>
	#include <boost/multiprecision/cpp_dec_float.hpp>
	using bll = boost::multiprecision::cpp_int;
	using bdouble = boost::multiprecision::cpp_dec_float_100;
#endif
#ifdef LOCAL_DEV
	void debug_impl() { std::cerr << '\n'; }
	template<typename Head, typename... Tail> void debug_impl(Head head, Tail... tail) { std::cerr << " " << head << (sizeof...(tail) ? "," : ""); debug_impl(tail...); }
	#define debug(...) do { std::cerr << "(" << #__VA_ARGS__ << ") ="; debug_impl(__VA_ARGS__); } while (false)
#else
	#define debug(...) do {} while (false)
#endif
#ifdef LOCAL_TEST
	#define BOOST_STACKTRACE_USE_ADDR2LINE
	#define BOOST_STACKTRACE_ADDR2LINE_LOCATION /usr/local/opt/binutils/bin/addr2line
	#define _GNU_SOURCE
	#include <boost/stacktrace.hpp>
	namespace std {
		template<typename T> class dvector : public std::vector<T> {
		public:
			dvector() : std::vector<T>() {}
			explicit dvector(size_t n, const T& value = T()) : std::vector<T>(n, value) {}
			dvector(const std::vector<T>& v) : std::vector<T>(v) {}
			dvector(const std::initializer_list<T> il) : std::vector<T>(il) {}
			dvector(const typename std::vector<T>::iterator first, const typename std::vector<T>::iterator last) : std::vector<T>(first, last) {}
			dvector(const std::string::iterator first, const std::string::iterator last) : std::vector<T>(first, last) {}
			T& operator[](size_t n) {
				try { return this->at(n); } catch (const std::exception& e) {
					std::cerr << boost::stacktrace::stacktrace() << '\n'; return this->at(n);
				}
			}
			const T& operator[](size_t n) const {
				try { return this->at(n); } catch (const std::exception& e) {
					std::cerr << boost::stacktrace::stacktrace() << '\n'; return this->at(n);
				}
			}
		};
	}
	class dbool {
	private:
		bool boolvalue;
	public:
		dbool() : boolvalue(false) {}
		dbool(bool b) : boolvalue(b) {}
		dbool(const dbool& b) : boolvalue(b.boolvalue) {}
		operator bool&() { return boolvalue; }
		operator const bool&() const { return boolvalue; }
	};
	template<typename T> std::ostream& operator<<(std::ostream& s, const std::dvector<T>& v) {
		for (size_t i = 0; i < v.size(); ++i){ s << v[i]; if (i < v.size() - 1) s << "\t"; } return s; }
	template<typename T> std::ostream& operator<<(std::ostream& s, const std::dvector<std::dvector<T>>& vv) {
		s << "\n"; for (size_t i = 0; i < vv.size(); ++i){ s << vv[i] << "\n"; } return s; }
	template<typename T> std::ostream& operator<<(std::ostream& s, const std::set<T>& se) {
		s << "{ "; for (auto itr = se.begin(); itr != se.end(); ++itr){ s << (*itr) << "\t"; } s << "}"; return s; }
	template<typename T> std::ostream& operator<<(std::ostream& s, const std::multiset<T>& se) {
		s << "{ "; for (auto itr = se.begin(); itr != se.end(); ++itr){ s << (*itr) << "\t"; } s << "}"; return s; }
	template <typename T, size_t N> std::ostream& operator<<(std::ostream& s, const std::array<T, N>& a) {
		s << "{ "; for (size_t i = 0; i < N; ++i){ s << a[i] << "\t"; } s << "}"; return s; }
	template<typename T1, typename T2> std::ostream& operator<<(std::ostream& s, const std::map<T1, T2>& m) {
		s << "{\n"; for (auto itr = m.begin(); itr != m.end(); ++itr){ s << "\t" << (*itr).first << " : " << (*itr).second << "\n"; } s << "}"; return s; }
	template<typename T1, typename T2> std::ostream& operator<<(std::ostream& s, const std::pair<T1, T2>& p) {
		return s << "(" << p.first << ", " << p.second << ")"; }
	#define vector dvector
	#define bool dbool
	class SIGFPE_exception : std::exception {};
	class SIGSEGV_exception : std::exception {};
	void catch_SIGFPE(int e) { std::cerr << boost::stacktrace::stacktrace() << '\n'; throw SIGFPE_exception();	}
	void catch_SIGSEGV(int e) { std::cerr << boost::stacktrace::stacktrace() << '\n'; throw SIGSEGV_exception(); }
	signed convertedmain();
	signed main() { signal(SIGFPE, catch_SIGFPE); signal(SIGSEGV, catch_SIGSEGV); return convertedmain(); }
	#define main() convertedmain()
#endif
//#define int long long
using ll = long long;
//constexpr int INF = 1e9;//INT_MAX=(1<<31)-1=2147483647
constexpr ll INF = (ll)1e18;//(1LL<<63)-1=9223372036854775807
constexpr ll MOD = (ll)1e9 + 7;
constexpr double EPS = 1e-9;
constexpr ll dx[4] = {1LL, 0LL, -1LL, 0LL};
constexpr ll dy[4] = {0LL, 1LL, 0LL, -1LL};
constexpr ll dx8[8] = {1LL, 0LL, -1LL, 0LL, 1LL, 1LL, -1LL, -1LL};
constexpr ll dy8[8] = {0LL, 1LL, 0LL, -1LL, 1LL, -1LL, 1LL, -1LL};
#define rep(i, n)   for(ll i=0, i##_length=(n); i< i##_length; ++i)
#define repeq(i, n) for(ll i=1, i##_length=(n); i<=i##_length; ++i)
#define rrep(i, n)   for(ll i=(n)-1; i>=0; --i)
#define rrepeq(i, n) for(ll i=(n)  ; i>=1; --i)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
void p() { std::cout << '\n'; }
template<typename Head, typename... Tail> void p(Head head, Tail... tail) { std::cout << head << (sizeof...(tail) ? " " : ""); p(tail...); }
template<typename T> inline void pv(std::vector<T>& v) { for(ll i=0, N=v.size(); i<N; i++) std::cout << v[i] << " \n"[i==N-1]; }
template<typename T> inline T gcd(T a, T b) { return b ? gcd(b,a%b) : a; }
template<typename T> inline T lcm(T a, T b) { return a / gcd(a,  b) * b; }
template<typename T> inline bool chmax(T& a, T b) { return a < b && (a = b, true); }
template<typename T> inline bool chmin(T& a, T b) { return a > b && (a = b, true); }
template<typename T> inline void uniq(std::vector<T>& v) { v.erase(std::unique(v.begin(), v.end()), v.end()); }

/*-----8<-----template-----8<-----*/

/*-----8<-----library-----8<-----*/

ll dfs(vector<vector<ll>> &g, ll v, ll p) {
	if(g[v].size()==1){
		return 0;
	}

	ll leaf=0;
	ll sum=0;
	for(ll nextv : g[v]){
		if(nextv==p) continue;
		ll t=dfs(g, nextv, v);
		if(t==0)leaf++;
		sum+=t;
	}
	
	if(leaf>1)sum+=leaf-1;
	return sum;

}

void solve() {
	ll N;
	cin>>N;
	vector<vector<ll>> g(N);
	rep(i,N-1){
		ll a,b;
		cin>>a>>b;
		g[a].push_back(b);
		g[b].push_back(a);
	}

	if([&]{
		rep(i,N)if(g[i].size()>2)return false;
		return true;
	}()){
		p(1);return;
	}

	ll start;
	rep(i,N){
		if(g[i].size()>2){
			start=i;
			break;
		}
	}

	ll ans=dfs(g,start,-1);
	p(ans);
}

signed main() {
	solve();
	return 0;
}