
"""simple docstring"""





import mpmath  # for roots of unity
import numpy as np






class     _UpperCAmelCase:



		def __init__(					self				,		__a=None				,		__a=None)       ->       Optional[int]:






							'''simple docstring'''
							# Input as list
							_UpperCamelCase							 =  list(poly_a or [0])[:]
							_UpperCamelCase							 =  list(poly_b or [0])[:]

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

							while self.polyB[-1] == 0:
												self.polyB.pop()
							_UpperCamelCase							 =  len(self.polyB)

							# Add 0 to make lengths equal a power of 2
							_UpperCamelCase							 =  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
							_UpperCamelCase							 =  complex(mpmath.root(x=1				,		n=self.c_max_length				,		k=1))

							# The product
							_UpperCamelCase							 =  self.__multiply()



		def 						UpperCAmelCase							(					self				,		__a)       ->       Dict:






							'''simple docstring'''
							_UpperCamelCase							 =  [[x] for x in self.polyA] if which == '''A''' else [[x] for x in self.polyB]
							# Corner case
							if len(__a) <= 1:
												return dft[0]
							#
							_UpperCamelCase							 =  self.c_max_length // 2
							while next_ncol > 0:
												_UpperCamelCase							 =  [[] for i in range(__a)]
												_UpperCamelCase							 =  self.root**next_ncol

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



		def 						UpperCAmelCase							(					self)       ->       str:






							'''simple docstring'''
							_UpperCamelCase							 =  self.__dft('''A''')
							_UpperCamelCase							 =  self.__dft('''B''')
							_UpperCamelCase							 =  [[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
							_UpperCamelCase							 =  2
							while next_ncol <= self.c_max_length:
												_UpperCamelCase							 =  [[] for i in range(__a)]
												_UpperCamelCase							 =  self.root ** (next_ncol // 2)
												_UpperCamelCase							 =  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
												_UpperCamelCase							 =  new_inverse_c
												next_ncol *= 2
							# Unpack
							_UpperCamelCase							 =  [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)       ->       int:






							'''simple docstring'''
							_UpperCamelCase							 =  '''A = ''' + ''' + '''.join(
							    F'''{coef}*x^{i}''' for coef, i in enumerate(self.polyA[: self.len_A]))
							_UpperCamelCase							 =  '''B = ''' + ''' + '''.join(
							    F'''{coef}*x^{i}''' for coef, i in enumerate(self.polyB[: self.len_B]))
							_UpperCamelCase							 =  '''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"""





class     _UpperCAmelCase:



		def __init__(					self)       ->       Optional[Any]:






							'''simple docstring'''
							_UpperCamelCase							 =  {}



		def 						UpperCAmelCase							(					self)       ->       None:






							'''simple docstring'''
							print(self.vertex)
							for i in self.vertex:
												print(__a				,		''' -> '''				,		''' -> '''.join([str(__a) for j in self.vertex[i]]))



		def 						UpperCAmelCase							(					self				,		__a				,		__a)       ->       None:






							'''simple docstring'''
							# check if vertex is already present,
							if from_vertex in self.vertex:
												self.vertex[from_vertex].append(__a)
							else:
												# else make a new vertex
												_UpperCamelCase							 =  [to_vertex]



		def 						UpperCAmelCase							(					self)       ->       None:






							'''simple docstring'''
							# visited array for storing already visited nodes
							_UpperCamelCase							 =  [False] * len(self.vertex)

							# call the recursive helper function
							for i in range(len(self.vertex)):
												if not visited[i]:
																	self.dfs_recursive(__a				,		__a)




		def 						UpperCAmelCase							(					self				,		__a				,		__a)       ->       None:






							'''simple docstring'''
							# mark start vertex as visited
							_UpperCamelCase							 =  True

							print(__a				,		end=''' ''')

							# Recur for all the vertices that are adjacent to this node
							for i in self.vertex:
												if not visited[i]:
																	self.dfs_recursive(__a				,		__a)


if __name__ == "__main__":
				_a														=		Graph()
				g.add_edge(0, 1)
				g.add_edge(0, 2)
				g.add_edge(1, 2)
				g.add_edge(2, 0)
				g.add_edge(2, 3)
				g.add_edge(3, 3)

				g.print_graph()
				print("""DFS:""")
				g.dfs()

				# OUTPUT:
				# 0  ->  1 -> 2
				# 1  ->  2
				# 2  ->  0 -> 3
				# 3  ->  3
				# DFS:
				#  0 1 2 3






