




from __future__ import annotations

from typing import Generic, TypeVar

UpperCAmelCase__				     = TypeVar("T")







class a (     Generic[T]  ):
						"""simple docstring"""

						def __init__( self :     Any				,							lowerCamelCase__ :     T				)    ->						Optional[int]:
													"""simple docstring"""


													__lowercase      =    data
													__lowercase      =    self
													__lowercase      =    0







class a (     Generic[T]  ):
						"""simple docstring"""

						def __init__( self :     Optional[int]				)    ->						Dict:
													"""simple docstring"""


													__lowercase      =    {}






						def     UpperCAmelCase_      ( self :     str				,							lowerCamelCase__ :     T				)    ->						List[str]:
													"""simple docstring"""


													__lowercase      =    DisjointSetTreeNode(_A				)






						def     UpperCAmelCase_      ( self :     List[Any]				,							lowerCamelCase__ :     T				)    ->						str:
													"""simple docstring"""


													__lowercase      =    self.map[data]
													if elem_ref != elem_ref.parent:
																				__lowercase      =    self.find_set(elem_ref.parent.data				)
													return elem_ref.parent






						def     UpperCAmelCase_      ( self :     List[Any]				,							lowerCamelCase__ :     DisjointSetTreeNode[T]				,							lowerCamelCase__ :     DisjointSetTreeNode[T]				)    ->						Any:
													"""simple docstring"""


													if nodea.rank > nodea.rank:
																				__lowercase      =    nodea
													else:
																				__lowercase      =    nodea
																				if nodea.rank == nodea.rank:
																											nodea.rank += 1






						def     UpperCAmelCase_      ( self :     List[Any]				,							lowerCamelCase__ :     T				,							lowerCamelCase__ :     T				)    ->						Optional[Any]:
													"""simple docstring"""


													self.link(self.find_set(_A				)				,							self.find_set(_A				)				)







class a (     Generic[T]  ):
						"""simple docstring"""

						def __init__( self :     Any				)    ->						int:
													"""simple docstring"""


													__lowercase      =    {}






						def     UpperCAmelCase_      ( self :     Optional[int]				,							lowerCamelCase__ :     T				)    ->						List[Any]:
													"""simple docstring"""


													if node not in self.connections:
																				__lowercase      =    {}






						def     UpperCAmelCase_      ( self :     Tuple				,							lowerCamelCase__ :     T				,							lowerCamelCase__ :     T				,							lowerCamelCase__ :     int				)    ->						str:
													"""simple docstring"""


													self.add_node(_A				)
													self.add_node(_A				)
													__lowercase      =    weight
													__lowercase      =    weight






						def     UpperCAmelCase_      ( self :     Optional[int]				)    ->						Union[str, Any]:
													"""simple docstring"""


													__lowercase      =    []
													__lowercase      =    set()
													for start in self.connections:
																				for end in self.connections[start]:
																											if (start, end) not in seen:
																																		seen.add((end, start)				)
																																		edges.append((start, end, self.connections[start][end])				)
													edges.sort(key=lambda lowerCamelCase__				: x[2]				)

													# creating the disjoint set
													__lowercase      =    DisjointSetTree[T]()
													for node in self.connections:
																				disjoint_set.make_set(_A				)

													# MST generation
													__lowercase      =    0
													__lowercase      =    0
													__lowercase      =    GraphUndirectedWeighted[T]()
													while num_edges < len(self.connections				) - 1:
																				__lowercase     ,     __lowercase     ,     __lowercase      =    edges[index]
																				index += 1
																				__lowercase      =    disjoint_set.find_set(_A				)
																				__lowercase      =    disjoint_set.find_set(_A				)
																				if parent_u != parent_v:
																											num_edges += 1
																											graph.add_edge(_A				,							_A				,							_A				)
																											disjoint_set.union(_A				,							_A				)
													return graph












import itertools
import string
from collections.abc import Generator, Iterable







def 		_A(       UpperCamelCase__							:			Iterable[str]				,       UpperCamelCase__							:			int				)    -> Generator[tuple[str, ...], None, None]:
							'''simple docstring'''


							__lowercase      =    iter(UpperCamelCase__				)
							while True:
														__lowercase      =    tuple(itertools.islice(UpperCamelCase__				,       UpperCamelCase__				)				)
														if not chunk:
																					return
														yield chunk







def 		_A(       UpperCamelCase__							:			str				)    -> str:
							'''simple docstring'''


							__lowercase      =    ''''''.join([c.upper() for c in dirty if c in string.ascii_letters]				)
							__lowercase      =    ''''''

							if len(UpperCamelCase__				) < 2:
														return dirty

							for i in range(len(UpperCamelCase__				) - 1				):
														clean += dirty[i]

														if dirty[i] == dirty[i + 1]:
																					clean += "X"

							clean += dirty[-1]

							if len(UpperCamelCase__				) & 1:
														clean += "X"

							return clean







def 		_A(       UpperCamelCase__							:			str				)    -> list[str]:
							'''simple docstring'''


							__lowercase      =    '''ABCDEFGHIKLMNOPQRSTUVWXYZ'''
							# we're using a list instead of a '2d' array because it makes the math
							# for setting up the table and doing the actual encoding/decoding simpler
							__lowercase      =    []

							# copy key chars into the table if they are in `alphabet` ignoring duplicates
							for char in key.upper():
														if char not in table and char in alphabet:
																					table.append(UpperCamelCase__				)

    # fill the rest of the table in with the remaining alphabet chars
							for char in alphabet:
														if char not in table:
																					table.append(UpperCamelCase__				)

							return table







def 		_A(       UpperCamelCase__							:			str				,       UpperCamelCase__							:			str				)    -> str:
							'''simple docstring'''


							__lowercase      =    generate_table(UpperCamelCase__				)
							__lowercase      =    prepare_input(UpperCamelCase__				)
							__lowercase      =    ''''''

							# https://en.wikipedia.org/wiki/Playfair_cipher#Description
							for chara, chara in chunker(UpperCamelCase__				,       2				):
														__lowercase     ,     __lowercase      =    divmod(table.index(UpperCamelCase__				)				,       5				)
														__lowercase     ,     __lowercase      =    divmod(table.index(UpperCamelCase__				)				,       5				)

														if rowa == rowa:
																					ciphertext += table[rowa * 5 + (cola + 1) % 5]
																					ciphertext += table[rowa * 5 + (cola + 1) % 5]
														elif cola == cola:
																					ciphertext += table[((rowa + 1) % 5) * 5 + cola]
																					ciphertext += table[((rowa + 1) % 5) * 5 + cola]
														else:  # rectangle
																					ciphertext += table[rowa * 5 + cola]
																					ciphertext += table[rowa * 5 + cola]

							return ciphertext







def 		_A(       UpperCamelCase__							:			str				,       UpperCamelCase__							:			str				)    -> str:
							'''simple docstring'''


							__lowercase      =    generate_table(UpperCamelCase__				)
							__lowercase      =    ''''''

							# https://en.wikipedia.org/wiki/Playfair_cipher#Description
							for chara, chara in chunker(UpperCamelCase__				,       2				):
														__lowercase     ,     __lowercase      =    divmod(table.index(UpperCamelCase__				)				,       5				)
														__lowercase     ,     __lowercase      =    divmod(table.index(UpperCamelCase__				)				,       5				)

														if rowa == rowa:
																					plaintext += table[rowa * 5 + (cola - 1) % 5]
																					plaintext += table[rowa * 5 + (cola - 1) % 5]
														elif cola == cola:
																					plaintext += table[((rowa - 1) % 5) * 5 + cola]
																					plaintext += table[((rowa - 1) % 5) * 5 + cola]
														else:  # rectangle
																					plaintext += table[rowa * 5 + cola]
																					plaintext += table[rowa * 5 + cola]

							return plaintext






