from math import factorial

__lowerCamelCase      :			dict[str, int]							       =		{str(digit): factorial(digit) for digit in range(10)}



def      __SCREAMING_SNAKE_CASE  ( __UpperCamelCase   :	int     )							-> int:







  """simple docstring"""





  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      __SCREAMING_SNAKE_CASE  ( __UpperCamelCase   :	int = 60			,					__UpperCamelCase   :	int = 1_00_00_00     )							-> int:







  """simple docstring"""





  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
  SCREAMING_SNAKE_CASE__      							=				0
  # the cached sizes of the previous chains
  SCREAMING_SNAKE_CASE__      							=				{}

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

    # Stop computing the chain when you find a cached size, a repeating item or the
    # length is greater then the desired one.
    SCREAMING_SNAKE_CASE__      							=				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
      SCREAMING_SNAKE_CASE__      							=				digit_factorial_sum(_UpperCAmelCase     )

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

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




import unittest

from transformers import is_torch_available
from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device


if is_torch_available():
   from transformers import AutoModelForSeqaSeqLM, AutoTokenizer







@require_torch
@require_sentencepiece
@require_tokenizers
class __snake_case    (						unittest.TestCase		):




   @slow
   def      __a						(   self      :    List[str]				):



     """simple docstring"""






     SCREAMING_SNAKE_CASE__      							=				AutoModelForSeqaSeqLM.from_pretrained("""google/mt5-small"""	,     return_dict=_lowercase				).to(_lowercase				)
     SCREAMING_SNAKE_CASE__      							=				AutoTokenizer.from_pretrained("""google/mt5-small"""				)

     SCREAMING_SNAKE_CASE__      							=				tokenizer("""Hello there"""	,     return_tensors="""pt"""				).input_ids
     SCREAMING_SNAKE_CASE__      							=				tokenizer("""Hi I am"""	,     return_tensors="""pt"""				).input_ids

     SCREAMING_SNAKE_CASE__      							=				model(input_ids.to(_lowercase				)	,     labels=labels.to(_lowercase				)				).loss
     SCREAMING_SNAKE_CASE__      							=				-(labels.shape[-1] * loss.item())

     SCREAMING_SNAKE_CASE__      							=				-84.91_27
     self.assertTrue(abs(mtf_score - EXPECTED_SCORE				) < 1E-4				)
