


from collections import defaultdict







class 	__lowercase    :





							"""simple docstring"""







							def __init__(      self			,						lowerCAmelCase__			,						lowerCAmelCase__       ):





										"""simple docstring"""




										SCREAMING_SNAKE_CASE_		:     Dict					=					total  # total no of tasks (N)

										# DP table will have a dimension of (2^M)*N
										# initially all values are set to -1
										SCREAMING_SNAKE_CASE_		:     Any					=					[
										    [-1 for i in range(total + 1       )] for j in range(2 ** len(lowerCAmelCase__       )       )
										]

										SCREAMING_SNAKE_CASE_		:     Dict					=					defaultdict(lowerCAmelCase__       )  # stores the list of persons for each task

										# final_mask is used to check if all persons are included by setting all bits
										# to 1
										SCREAMING_SNAKE_CASE_		:     Optional[int]					=					(1 << len(lowerCAmelCase__       )) - 1






							def 					UpperCamelCase__     (      self			,						lowerCAmelCase__			,						lowerCAmelCase__       ):





										"""simple docstring"""




										if mask == self.final_mask:
													return 1

										# if not everyone gets the task and no more tasks are available, return 0
										if task_no > self.total_tasks:
													return 0

										# if case already considered
										if self.dp[mask][task_no] != -1:
													return self.dp[mask][task_no]

										# Number of ways when we don't this task in the arrangement
										SCREAMING_SNAKE_CASE_		:     int					=					self.count_ways_until(lowerCAmelCase__			,						task_no + 1       )

										# now assign the tasks one by one to all possible persons and recursively
										# assign for the remaining tasks.
										if task_no in self.task:
													for p in self.task[task_no]:
																# if p is already given a task
																if mask & (1 << p):
																			continue

																# assign this task to p and change the mask value. And recursively
																# assign tasks with the new mask value.
																total_ways_util += self.count_ways_until(mask | (1 << p)			,						task_no + 1       )

        # save the value.
										SCREAMING_SNAKE_CASE_		:     Optional[int]					=					total_ways_util

										return self.dp[mask][task_no]






							def 					UpperCamelCase__     (      self			,						lowerCAmelCase__       ):





										"""simple docstring"""




										for i in range(len(lowerCAmelCase__       )       ):
													for j in task_performed[i]:
																self.task[j].append(lowerCAmelCase__       )

        # call the function to fill the DP table, final answer is stored in dp[0][1]
										return self.count_ways_until(0			,						1       )


if __name__ == "__main__":
				lowerCAmelCase__			:      str								=5  # total no of tasks (the value of N)

				# the list of tasks that can be done by M persons.
				lowerCAmelCase__			:      List[Any]								=[[1, 3, 4], [1, 2, 5], [3, 4]]
				print(
				    AssignmentUsingBitmask(task_performed, total_tasks).count_no_of_ways(
				        task_performed
				    )
				)









def 						a__			(				A__,      A__				):
			SCREAMING_SNAKE_CASE_		:     Optional[Any]					=					''
			for i in table:
						res += inp[i - 1]
			return res






def 						a__			(				A__				):
			return data[1:] + data[0]






def 						a__			(				A__,      A__				):
			SCREAMING_SNAKE_CASE_		:     Optional[int]					=					''
			for i in range(len(A__				)				):
						if a[i] == b[i]:
									res += "0"
						else:
									res += "1"
			return res






def 						a__			(				A__,      A__				):
			SCREAMING_SNAKE_CASE_		:     Tuple					=					int('0b' + data[0] + data[-1],      2				)
			SCREAMING_SNAKE_CASE_		:     Tuple					=					int('0b' + data[1:3],      2				)
			return bin(s[row][col]				)[2:]






def 						a__			(				A__,      A__,      A__,      A__,      A__				):
			SCREAMING_SNAKE_CASE_		:     List[Any]					=					message[:4]
			SCREAMING_SNAKE_CASE_		:     int					=					message[4:]
			SCREAMING_SNAKE_CASE_		:     List[str]					=					apply_table(A__,      A__				)
			SCREAMING_SNAKE_CASE_		:     Dict					=					xor(A__,      A__				)
			SCREAMING_SNAKE_CASE_		:     Any					=					apply_sbox(A__,      temp[:4]				)  # noqa: E741
			SCREAMING_SNAKE_CASE_		:     List[Any]					=					apply_sbox(A__,      temp[4:]				)
			SCREAMING_SNAKE_CASE_		:     Any					=					'0' * (2 - len(A__				)) + l  # noqa: E741
			SCREAMING_SNAKE_CASE_		:     List[Any]					=					'0' * (2 - len(A__				)) + r
			SCREAMING_SNAKE_CASE_		:     Optional[int]					=					apply_table(l + r,      A__				)
			SCREAMING_SNAKE_CASE_		:     Dict					=					xor(A__,      A__				)
			return temp + right


if __name__ == "__main__":
				lowerCAmelCase__			:      Optional[Any]								=input('Enter 10 bit key: ')
				lowerCAmelCase__			:      int								=input('Enter 8 bit message: ')

				lowerCAmelCase__			:      Any								=[6, 3, 7, 4, 8, 5, 10, 9]
				lowerCAmelCase__			:      List[str]								=[3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
				lowerCAmelCase__			:      Dict								=[2, 4, 3, 1]
				lowerCAmelCase__			:      Dict								=[2, 6, 3, 1, 4, 8, 5, 7]
				lowerCAmelCase__			:      Union[str, Any]								=[4, 1, 3, 5, 7, 2, 8, 6]
				lowerCAmelCase__			:      Dict								=[4, 1, 2, 3, 2, 3, 4, 1]
				lowerCAmelCase__			:      str								=[[1, 0, 3, 2], [3, 2, 1, 0], [0, 2, 1, 3], [3, 1, 3, 2]]
				lowerCAmelCase__			:      Any								=[[0, 1, 2, 3], [2, 0, 1, 3], [3, 0, 1, 0], [2, 1, 0, 3]]

				# key generation
				lowerCAmelCase__			:      Dict								=apply_table(key, paa_table)
				lowerCAmelCase__			:      List[str]								=temp[:5]
				lowerCAmelCase__			:      List[Any]								=temp[5:]
				lowerCAmelCase__			:      Tuple								=left_shift(left)
				lowerCAmelCase__			:      Optional[Any]								=left_shift(right)
				lowerCAmelCase__			:      Optional[int]								=apply_table(left + right, pa_table)
				lowerCAmelCase__			:      Optional[Any]								=left_shift(left)
				lowerCAmelCase__			:      Optional[Any]								=left_shift(right)
				lowerCAmelCase__			:      List[str]								=left_shift(left)
				lowerCAmelCase__			:      Optional[int]								=left_shift(right)
				lowerCAmelCase__			:      Tuple								=apply_table(left + right, pa_table)

				# encryption
				lowerCAmelCase__			:      Tuple								=apply_table(message, IP)
				lowerCAmelCase__			:      List[Any]								=function(expansion, sa, sa, keya, temp)
				lowerCAmelCase__			:      str								=temp[4:] + temp[:4]
				lowerCAmelCase__			:      Optional[Any]								=function(expansion, sa, sa, keya, temp)
				lowerCAmelCase__			:      Optional[int]								=apply_table(temp, IP_inv)
				print('Cipher text is:', CT)

				# decryption
				lowerCAmelCase__			:      Union[str, Any]								=apply_table(CT, IP)
				lowerCAmelCase__			:      Tuple								=function(expansion, sa, sa, keya, temp)
				lowerCAmelCase__			:      Union[str, Any]								=temp[4:] + temp[:4]
				lowerCAmelCase__			:      Dict								=function(expansion, sa, sa, keya, temp)
				lowerCAmelCase__			:      int								=apply_table(temp, IP_inv)
				print('Plain text after decypting is:', PT)





