You're given a tree with $n$ vertices.

Your task is to determine the maximum possible number of edges that can be removed in such a way that all the remaining connected components will have even size.


-----Input-----

The first line contains an integer $n$ ($1 \le n \le 10^5$) denoting the size of the tree. 

The next $n - 1$ lines contain two integers $u$, $v$ ($1 \le u, v \le n$) each, describing the vertices connected by the $i$-th edge.

It's guaranteed that the given edges form a tree.


-----Output-----

Output a single integer $k$ — the maximum number of edges that can be removed to leave all connected components with even size, or $-1$ if it is impossible to remove edges in order to satisfy this property.


-----Examples-----
Input
4
2 4
4 1
3 1

Output
1
Input
3
1 2
1 3

Output
-1
Input
10
7 1
8 4
8 10
4 7
6 5
9 3
3 5
2 10
2 5

Output
4
Input
2
1 2

Output
0


-----Note-----

In the first example you can remove the edge between vertices $1$ and $4$. The graph after that will have two connected components with two vertices in each.

In the second example you can't remove edges in such a way that all components have even number of vertices, so the answer is $-1$.

Difficulty: MEDIUM

Solutions:
n = int(input())
if n % 2 != 0:
	print(-1)
	return
links = [[1, set()] for i in range(1, n + 1)]
W = 0
L = 1
i = 0
while i < n - 1:
	i += 1
	[a, b] = [int(x) for x in input().split()]
	links[a - 1][L].add(b - 1)
	links[b - 1][L].add(a - 1)
count = sear = cur = 0
while sear < n:
	li = cur
	l = links[li]
	if len(l[L]) != 1:
		if sear == cur:
			sear += 1
		cur = sear
		continue
	mi = l[L].pop()
	m = links[mi]
	if l[W] % 2 == 0:
		count += 1
	else:
		m[W] += 1
	m[L].remove(li)
	if mi < sear:
		cur = mi
	else:
		sear += 1
		cur = sear
print(count)


import sys
Ri = lambda : [int(x) for x in sys.stdin.readline().split()]
ri = lambda : sys.stdin.readline().strip()

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 18
MOD = 10 ** 9 + 7
n = int(ri())
lis = [[] for i in range(n)]
for _ in range(n - 1):
	(a, b) = Ri()
	a -= 1
	b -= 1
	lis[a].append(b)
	lis[b].append(a)
visit = [-1] * n
no = [1] * n
sta = [0]
visit[0] = True
if n & 1 == 1:
	print(-1)
else:
	while len(sta) > 0:
		top = sta[-1]
		ret = True
		for i in range(len(lis[top])):
			if visit[lis[top][i]] == -1:
				visit[lis[top][i]] = top
				ret = False
				sta.append(lis[top][i])
		if ret:
			if top != 0:
				no[visit[top]] += no[top]
			sta.pop()
	ans = 0
	no = no[1:]
	for i in no:
		if i & 1 == 0:
			ans += 1
	print(ans)


import sys, os, io

def rs():
	return sys.stdin.readline().rstrip()

def ri():
	return int(sys.stdin.readline())

def ria():
	return list(map(int, sys.stdin.readline().split()))

def ws(s):
	sys.stdout.write(s + '\n')

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')
import math, datetime, functools, itertools, operator, bisect, fractions, statistics
from collections import deque, defaultdict, OrderedDict, Counter
from fractions import Fraction
from decimal import Decimal
from sys import stdout
from heapq import heappush, heappop, heapify, _heapify_max, _heappop_max, nsmallest, nlargest
sys.setrecursionlimit(111111)
INF = 99999999999999999999999999999999

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def main():
	mod = 1000000007
	starttime = datetime.datetime.now()
	if os.path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	tc = 1
	for _ in range(tc):
		n = ri()
		graph = [[] for i in range(n + 1)]
		for i in range(n - 1):
			(a, b) = ria()
			graph[a].append(b)
			graph[b].append(a)
		if n % 2:
			wi(-1)
			exit()

		def dfs():
			start = 1
			dp = [0] * (n + 1)
			(visited, finished) = ([False] * (n + 1), [False] * (n + 1))
			stack = [start]
			while stack:
				start = stack[-1]
				if not visited[start]:
					visited[start] = True
					for child in graph[start]:
						if not visited[child]:
							stack.append(child)
				else:
					stack.pop()
					dp[start] += 1
					for child in graph[start]:
						if finished[child]:
							dp[start] += dp[child]
					finished[start] = True
			return dp
		size = dfs()
		count = 0
		for i in range(2, n + 1):
			if size[i] % 2 == 0:
				count += 1
		wi(count)
	endtime = datetime.datetime.now()
	time = (endtime - starttime).total_seconds() * 1000
	if os.path.exists('input.txt'):
		print('Time:', time, 'ms')

class FastReader(io.IOBase):
	newlines = 0

	def __init__(self, fd, chunk_size=1024 * 8):
		self._fd = fd
		self._chunk_size = chunk_size
		self.buffer = io.BytesIO()

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self, size=-1):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size if size == -1 else size))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

class FastWriter(io.IOBase):

	def __init__(self, fd):
		self._fd = fd
		self.buffer = io.BytesIO()
		self.write = self.buffer.write

	def flush(self):
		os.write(self._fd, self.buffer.getvalue())
		(self.buffer.truncate(0), self.buffer.seek(0))

class FastStdin(io.IOBase):

	def __init__(self, fd=0):
		self.buffer = FastReader(fd)
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

class FastStdout(io.IOBase):

	def __init__(self, fd=1):
		self.buffer = FastWriter(fd)
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.flush = self.buffer.flush
sys.stdin = FastStdin()
sys.stdout = FastStdout()
main()


n = int(input())
tr = [[] for i in range(n)]
for _ in range(n - 1):
	(u, v) = map(int, input().split())
	tr[u - 1].append(v - 1)
	tr[v - 1].append(u - 1)
if n % 2:
	print(-1)
	exit()
c = [1] * n
par = [-1] * n
par[0] = 0
q = [0]
while q:
	ver = q[-1]
	flag = False
	for to in tr[ver]:
		if par[to] == -1:
			par[to] = ver
			q.append(to)
			flag = True
	if not flag:
		q.pop()
		c[par[ver]] += c[ver]
ans = 0
for i in range(1, n):
	if c[i] % 2 == 0:
		ans += 1
print(ans)


def dfs(node):
	par[1] = 1
	stack = [1]
	ans = 0
	while stack:
		k = stack[-1]
		f = 0
		for i in g[k]:
			if par[i] == -1:
				par[i] = k
				stack.append(i)
				f = 1
		if f == 0:
			k = stack.pop()
			subtree[par[k]] += subtree[k]
	for i in subtree[2:]:
		if i % 2 == 0:
			ans = ans + 1
	print(ans)
n = int(input())
g = {}
for i in range(1, n + 1):
	g[i] = []
for i in range(1, n):
	(a, b) = map(int, input().split())
	g[a].append(b)
	g[b].append(a)
par = [-1 for i in range(n + 1)]
subtree = [1 for i in range(n + 1)]
if n % 2:
	print(-1)
else:
	dfs(1)


from collections import deque
from array import array

def main():
	n = int(input())
	neis = [[] for i in range(n + 1)]
	for _ in range(n - 1):
		(u, v) = map(int, input().split())
		neis[u].append(v)
		neis[v].append(u)

	def fake_dfs(start_point):
		nonlocal neis
		vis = array('I', (0 for _ in range(n + 1)))
		nodes = array('I', (1 for _ in range(n + 1)))
		pre = array('I', (0 for _ in range(n + 1)))
		cut = 0
		q = deque()
		q.append(start_point)
		pre[start_point] = start_point
		while len(q) > 0:
			top = q[-1]
			if vis[top] < len(neis[top]):
				nei = neis[top][vis[top]]
				vis[top] += 1
				if nei != pre[top]:
					q.append(nei)
					pre[nei] = top
			else:
				if top != start_point:
					nodes[pre[top]] += nodes[top]
					if nodes[top] & 1 == 0:
						cut += 1
				q.pop()
		if nodes[1] & 1 == 0:
			print(cut)
		else:
			print(-1)
	fake_dfs(1)
main()


from collections import defaultdict
import threading
from sys import stdin, setrecursionlimit
setrecursionlimit(300000)
input = stdin.readline

def dfs(node, g, par, sz):
	for i in g[node]:
		if i != par:
			sz[node] += dfs(i, g, node, sz)
	return sz[node] + 1

def main():
	n = int(input())
	if n % 2 != 0:
		print(-1)
		exit(0)
	g = defaultdict(list)
	for i in range(n - 1):
		(x, y) = map(int, input().strip().split())
		g[x - 1].append(y - 1)
		g[y - 1].append(x - 1)
	sz = [0] * n
	tt = []
	dfs(0, g, -1, sz)
	res = 0
	for i in range(1, n):
		if sz[i] % 2 != 0:
			res += 1
	print(res)
threading.stack_size(10 ** 8)
t = threading.Thread(target=main)
t.start()
t.join()


n = int(input())
if n & 1 > 0:
	print(-1)
	exit()
g = [[] for i in range(n)]
for i in range(n - 1):
	(u, v) = map(int, input().split())
	u -= 1
	v -= 1
	g[u].append(v)
	g[v].append(u)
c = [1] * n
v = [-1] * n
v[0] = 0
q = [0]
while q:
	x = q[-1]
	flag = False
	for to in g[x]:
		if v[to] == -1:
			v[to] = x
			q.append(to)
			flag = True
	if not flag:
		q.pop()
		c[v[x]] += c[x]
ans = 0
for j in c[1:]:
	if j & 1 < 1:
		ans += 1
print(ans)


n = int(input())
d = {i: [] for i in range(1, n + 1)}
for i in range(n - 1):
	(a, b) = map(int, input().split())
	d[a].append(b)
	d[b].append(a)
if n & 1:
	print(-1)
else:
	val = [1 for i in range(n + 1)]
	par = [-1 for i in range(n + 1)]
	par[1] = 1
	stack = [1]
	while stack:
		u = stack[-1]
		f = 0
		for i in d[u]:
			if par[i] == -1:
				par[i] = u
				stack.append(i)
				f = 1
		if f == 0:
			stack.pop()
			val[par[u]] += val[u]
	ans = 0
	for i in range(2, n + 1):
		if val[i] % 2 == 0:
			ans += 1
	print(ans)


n = int(input())
graph = [[] for i in range(n + 1)]
for i in range(n - 1):
	(u, v) = list(map(int, input().split()))
	graph[u].append(v)
	graph[v].append(u)
if n % 2 != 0:
	print(-1)
	exit()
subtree_size = [1 for i in range(n + 1)]
par = [-1 for i in range(n + 1)]
par[1] = 1
st = [1]
while st != []:
	u = st[-1]
	f = 0
	for v in graph[u]:
		if par[v] == -1:
			par[v] = u
			st.append(v)
			f = 1
	if f == 0:
		st.pop()
		subtree_size[par[u]] += subtree_size[u]
res = 0
for i in range(2, len(subtree_size)):
	if subtree_size[i] % 2 == 0:
		res += 1
print(res)


from collections import defaultdict
for _ in range(1):
	n = int(input())
	tree = defaultdict(list)
	for i in range(n - 1):
		(u, v) = map(int, input().split())
		tree[u].append(v)
		tree[v].append(u)
	if len(tree) % 2 or n == 1:
		print(-1)
		exit(0)
	subtree_count = [1 for i in range(n + 1)]
	visited = [-1 for i in range(n + 1)]
	stack = [1]
	while stack:
		cn = stack[-1]
		found = 0
		for nn in tree[cn]:
			if visited[nn] == -1:
				found = 1
				visited[nn] = cn
				stack.append(nn)
		if not found:
			stack.pop()
			subtree_count[visited[cn]] += subtree_count[cn]
	edges = 0
	for count_ in subtree_count[2:]:
		if count_ % 2 == 0:
			edges += 1
	print(edges)