


"""simple docstring"""


from __future__ import annotations
class   _UpperCamelCase  :
							'''simple docstring'''







							def __init__(     self    ,   __a = 0	):
										__lowerCAmelCase				    =			key

							def 			snake_case				(     self    ,   __a    ,   __a	):
										assert isinstance(__a    ,   __a	) and isinstance(__a    ,   __a	)

										__lowerCAmelCase				    =			key or self.__key or 1

										# make sure key is an appropriate size
										key %= 2_55

										return [chr(ord(__a	) ^ key	) for ch in content]

							def 			snake_case				(     self    ,   __a    ,   __a	):
										assert isinstance(__a    ,   __a	) and isinstance(__a    ,   __a	)

										__lowerCAmelCase				    =			key or self.__key or 1

										# make sure key is an appropriate size
										key %= 2_55

										return [chr(ord(__a	) ^ key	) for ch in content]

							def 			snake_case				(     self    ,   __a    ,   __a = 0	):
										assert isinstance(__a    ,   __a	) and isinstance(__a    ,   __a	)

										__lowerCAmelCase				    =			key or self.__key or 1

										# make sure key can be any size
										while key > 2_55:
													key -= 2_55

										# This will be returned
										__lowerCAmelCase				    =			""

										for ch in content:
													ans += chr(ord(__a	) ^ key	)

										return ans

							def 			snake_case				(     self    ,   __a    ,   __a = 0	):
										assert isinstance(__a    ,   __a	) and isinstance(__a    ,   __a	)

										__lowerCAmelCase				    =			key or self.__key or 1

										# make sure key can be any size
										while key > 2_55:
													key -= 2_55

										# This will be returned
										__lowerCAmelCase				    =			""

										for ch in content:
													ans += chr(ord(__a	) ^ key	)

										return ans

							def 			snake_case				(     self    ,   __a    ,   __a = 0	):
										assert isinstance(__a    ,   __a	) and isinstance(__a    ,   __a	)

										try:
													with open(__a	) as fin, open("encrypt.out"    ,   "w+"	) as fout:
																# actual encrypt-process
																for line in fin:
																			fout.write(self.encrypt_string(__a    ,   __a	)	)

										except OSError:
													return False

										return True



							def 			snake_case				(     self    ,   __a    ,   __a	):
										assert isinstance(__a    ,   __a	) and isinstance(__a    ,   __a	)

										try:
													with open(__a	) as fin, open("decrypt.out"    ,   "w+"	) as fout:
																# actual encrypt-process
																for line in fin:
																			fout.write(self.decrypt_string(__a    ,   __a	)	)

										except OSError:
													return False

										return True


# Tests
# crypt = XORCipher()
# key = 67

# # test encrypt
# print(crypt.encrypt("hallo welt",key))
# # test decrypt
# print(crypt.decrypt(crypt.encrypt("hallo welt",key), key))

# # test encrypt_string
# print(crypt.encrypt_string("hallo welt",key))

# # test decrypt_string
# print(crypt.decrypt_string(crypt.encrypt_string("hallo welt",key),key))

# if (crypt.encrypt_file("test.txt",key)):
#       print("encrypt successful")
# else:
#       print("encrypt unsuccessful")

# if (crypt.decrypt_file("encrypt.out",key)):
#       print("decrypt successful")
# else:
#       print("decrypt unsuccessful")












from math import factorial

UpperCAmelCase__				   =		{str(digit): factorial(digit) for digit in range(10)}
def 						_a    (      a :int )							->			int:
 if not isinstance(a	,							a ):
  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(a ) )
def 						_a    (      a :int = 60	,							a :int = 1_000_000 )							->			int:

 if not isinstance(a	,							a ) or not isinstance(a	,							a ):
  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	,							a ):
  # 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(a )
   chain_set_length += 1
   a		  =      digit_factorial_sum(a )

  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()}""")


