



'''simple docstring'''



import mpmath  # for roots of unity
import numpy as np
class 						lowerCamelCase_				:







						def __init__(	self :   List[Any]					,     lowerCAmelCase__ :   List[str]=None					,     lowerCAmelCase__ :   Optional[int]=None					):

													"""simple docstring"""
													# Input as list
													SCREAMING_SNAKE_CASE       :   Any         =      list(poly_a or [0]					)[:]
													SCREAMING_SNAKE_CASE       :   List[str]         =      list(poly_b or [0]					)[:]

													# Remove leading zero coefficients
													while self.polyA[-1] == 0:
																				self.polyA.pop()
													SCREAMING_SNAKE_CASE       :   Dict         =      len(self.polyA					)

													while self.polyB[-1] == 0:
																				self.polyB.pop()
													SCREAMING_SNAKE_CASE       :   Optional[Any]         =      len(self.polyB					)

													# Add 0 to make lengths equal a power of 2
													SCREAMING_SNAKE_CASE       :   Optional[int]         =      int(
													    2 ** np.ceil(np.loga(len(self.polyA					) + len(self.polyB					) - 1					)					)					)

													while len(self.polyA					) < self.c_max_length:
																				self.polyA.append(0					)
													while len(self.polyB					) < self.c_max_length:
																				self.polyB.append(0					)
													# A complex root used for the fourier transform
													SCREAMING_SNAKE_CASE       :   Tuple         =      complex(mpmath.root(x=1					,     n=self.c_max_length					,     k=1					)					)

													# The product
													SCREAMING_SNAKE_CASE       :   Optional[Any]         =      self.__multiply()







						def        __lowercase     (	self :   int					,     lowerCAmelCase__ :   List[Any]					):

													"""simple docstring"""
													SCREAMING_SNAKE_CASE       :   List[str]         =      [[x] for x in self.polyA] if which == '''A''' else [[x] for x in self.polyB]
													# Corner case
													if len(lowerCAmelCase__					) <= 1:
																				return dft[0]
													#
													SCREAMING_SNAKE_CASE       :   List[str]         =      self.c_max_length // 2
													while next_ncol > 0:
																				SCREAMING_SNAKE_CASE       :   Optional[int]         =      [[] for i in range(lowerCAmelCase__					)]
																				SCREAMING_SNAKE_CASE       :   List[Any]         =      self.root**next_ncol

																				# First half of next step
																				SCREAMING_SNAKE_CASE       :   Union[str, Any]         =      1
																				for j in range(self.c_max_length // (next_ncol * 2)					):
																											for i in range(lowerCAmelCase__					):
																																		new_dft[i].append(dft[i][j] + current_root * dft[i + next_ncol][j]					)
																											current_root *= root
																				# Second half of next step
																				SCREAMING_SNAKE_CASE       :   Union[str, Any]         =      1
																				for j in range(self.c_max_length // (next_ncol * 2)					):
																											for i in range(lowerCAmelCase__					):
																																		new_dft[i].append(dft[i][j] - current_root * dft[i + next_ncol][j]					)
																											current_root *= root
																				# Update
																				SCREAMING_SNAKE_CASE       :   List[str]         =      new_dft
																				SCREAMING_SNAKE_CASE       :   Union[str, Any]         =      next_ncol // 2
													return dft[0]







						def        __lowercase     (	self :   Optional[int]					):

													"""simple docstring"""
													SCREAMING_SNAKE_CASE       :   Tuple         =      self.__dft('''A'''					)
													SCREAMING_SNAKE_CASE       :   Optional[int]         =      self.__dft('''B'''					)
													SCREAMING_SNAKE_CASE       :   str         =      [[dft_a[i] * dft_b[i] for i in range(self.c_max_length					)]]
													del dft_a
													del dft_b

													# Corner Case
													if len(inverce_c[0]					) <= 1:
																				return inverce_c[0]
													# Inverse DFT
													SCREAMING_SNAKE_CASE       :   Dict         =      2
													while next_ncol <= self.c_max_length:
																				SCREAMING_SNAKE_CASE       :   Optional[Any]         =      [[] for i in range(lowerCAmelCase__					)]
																				SCREAMING_SNAKE_CASE       :   Union[str, Any]         =      self.root ** (next_ncol // 2)
																				SCREAMING_SNAKE_CASE       :   List[Any]         =      1
																				# First half of next step
																				for j in range(self.c_max_length // next_ncol					):
																											for i in range(next_ncol // 2					):
																																		# Even positions
																																		new_inverse_c[i].append(
																																		    (
																																		        inverce_c[i][j]
																																		        + inverce_c[i][j + self.c_max_length // next_ncol]
																																		    )
																																		    / 2					)
																																		# Odd positions
																																		new_inverse_c[i + next_ncol // 2].append(
																																		    (
																																		        inverce_c[i][j]
																																		        - inverce_c[i][j + self.c_max_length // next_ncol]
																																		    )
																																		    / (2 * current_root)					)
																											current_root *= root
																				# Update
																				SCREAMING_SNAKE_CASE       :   int         =      new_inverse_c
																				next_ncol *= 2
													# Unpack
													SCREAMING_SNAKE_CASE       :   Any         =      [round(x[0].real					,     8					) + round(x[0].imag					,     8					) * 1j for x in inverce_c]

													# Remove leading 0's
													while inverce_c[-1] == 0:
																				inverce_c.pop()
													return inverce_c







						def __str__(	self :   Optional[Any]					):

													"""simple docstring"""
													SCREAMING_SNAKE_CASE       :   List[str]         =      '''A = ''' + ''' + '''.join(
													    F"""{coef}*x^{i}""" for coef, i in enumerate(self.polyA[: self.len_A]					)					)
													SCREAMING_SNAKE_CASE       :   Optional[Any]         =      '''B = ''' + ''' + '''.join(
													    F"""{coef}*x^{i}""" for coef, i in enumerate(self.polyB[: self.len_B]					)					)
													SCREAMING_SNAKE_CASE       :   Dict         =      '''A*B = ''' + ''' + '''.join(
													    F"""{coef}*x^{i}""" for coef, i in enumerate(self.product					)					)

													return F"""{a}\n{b}\n{c}"""


# Unit tests
if __name__ == "__main__":
							import doctest

							doctest.testmod()









'''simple docstring'''



from collections import defaultdict
def        UpperCAmelCase (    A	:					int					):
							SCREAMING_SNAKE_CASE       :   List[Any]         =      1
							SCREAMING_SNAKE_CASE       :   Dict         =      True
							for v in tree[start]:
														if v not in visited:
																					ret += dfs(A					)
							if ret % 2 == 0:
														cuts.append(A					)
							return ret
def        UpperCAmelCase (    ):
							dfs(1					)


if __name__ == "__main__":
							lowerCAmelCase_      ,				lowerCAmelCase_  :							Dict             =    10, 9
							lowerCAmelCase_  :							Dict             =    defaultdict(list)
							lowerCAmelCase_  :							dict[int, bool]             =    {}
							lowerCAmelCase_  :							list[int]             =    []
							lowerCAmelCase_  :							Optional[Any]             =    0
							lowerCAmelCase_  :							Dict             =    [(2, 1), (3, 1), (4, 3), (5, 2), (6, 1), (7, 2), (8, 6), (9, 8), (10, 8)]
							for u, v in edges:
														tree[u].append(v)
														tree[v].append(u)
							even_tree()
							print(len(cuts) - 1)




