



from math import factorial

SCREAMING_SNAKE_CASE__   			=   {str(digit): factorial(digit) for digit in range(1_0)}


def A    (							__UpperCamelCase       )    ->   int:
			if not isinstance(__UpperCamelCase			,						__UpperCamelCase       ):
						raise TypeError('Parameter number must be int'       )

			if number < 0:
						raise ValueError('Parameter number must be greater than or equal to 0'       )

			# Converts number in string to iterate on its digits and adds its factorial.
			return sum(DIGIT_FACTORIAL[digit] for digit in str(__UpperCamelCase       )       )


def A    (							__UpperCamelCase = 60			,						__UpperCamelCase = 1_000_000       )    ->   int:

			if not isinstance(__UpperCamelCase			,						__UpperCamelCase       ) or not isinstance(__UpperCamelCase			,						__UpperCamelCase       ):
						raise TypeError('Parameters chain_length and number_limit must be int'       )

			if chain_length <= 0 or number_limit <= 0:
						raise ValueError(
						    'Parameters chain_length and number_limit must be greater than 0'       )

			# the counter for the chains with the exact desired length
			A__	  =     0
			# the cached sizes of the previous chains
			A__	  =     {}

			for start_chain_element in range(1			,						__UpperCamelCase       ):
						# The temporary set will contain the elements of the chain
						A__	  =     set()
						A__	  =     0

						# Stop computing the chain when you find a cached size, a repeating item or the
						# length is greater then the desired one.
						A__	  =     start_chain_element
						while (
						    chain_element not in chain_sets_lengths
						    and chain_element not in chain_set
						    and chain_set_length <= chain_length
						):
									chain_set.add(__UpperCamelCase       )
									chain_set_length += 1
									A__	  =     digit_factorial_sum(__UpperCamelCase       )

						if chain_element in chain_sets_lengths:
									chain_set_length += chain_sets_lengths[chain_element]

						A__	  =     chain_set_length

						# If chain contains the exact amount of elements increase the counter
						if chain_set_length == chain_length:
									chains_counter += 1

			return chains_counter


if __name__ == "__main__":
							import doctest

							doctest.testmod()
							print(f'{solution()}')





"""simple docstring"""



from collections import defaultdict
class 						__UpperCAmelCase    :







			'''simple docstring'''





			def __init__(			self   ,      snake_case_   ,      snake_case_							):







										'''simple docstring'''


										A__       :     Tuple								=			total  # total no of tasks (N)

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

										A__       :     Optional[int]								=			defaultdict(snake_case_							)  # 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
										A__       :     Optional[int]								=			(1 << len(snake_case_							)) - 1





			def 		lowerCamelCase					(			self   ,      snake_case_   ,      snake_case_							):







										'''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
										A__       :     Optional[int]								=			self.count_ways_until(snake_case_   ,      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.
										A__       :     List[str]								=			total_ways_util

										return self.dp[mask][task_no]





			def 		lowerCamelCase					(			self   ,      snake_case_							):







										'''simple docstring'''


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

        # 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__":
				_UpperCamelCase								=		5  # total no of tasks (the value of N)

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





