






"""simple docstring"""





UpperCamelCase					=     {
    """0""": 1,
    """1""": 1,
    """2""": 2,
    """3""": 6,
    """4""": 24,
    """5""": 1_20,
    """6""": 7_20,
    """7""": 50_40,
    """8""": 4_03_20,
    """9""": 36_28_80,
}

UpperCamelCase					=     {1_45: 1_45}

UpperCamelCase					=     {
    1_45: 0,
    1_69: 3,
    3_63_01: 3,
    14_54: 3,
    8_71: 2,
    4_53_61: 2,
    8_72: 2,
}






def 							A(    snake_case_						):
       """simple docstring"""





       if n in CACHE_SUM_DIGIT_FACTORIALS:
              return CACHE_SUM_DIGIT_FACTORIALS[n]
       lowercase__:							Union[str, Any]         =     sum(DIGIT_FACTORIALS[let] for let in str(snake_case_						)						)
       lowercase__:							int         =     ret
       return ret






def 							A(    snake_case_		,  snake_case_ = None						):
       """simple docstring"""





       lowercase__:							Optional[Any]         =     previous or set()
       if n in CHAIN_LENGTH_CACHE:
              return CHAIN_LENGTH_CACHE[n]
       lowercase__:							Tuple         =     sum_digit_factorials(snake_case_						)
       if next_number in previous:
              lowercase__:							List[str]         =     0
              return 0
       else:
              previous.add(snake_case_						)
              lowercase__:							str         =     1 + chain_length(snake_case_		,  snake_case_						)
              lowercase__:							Union[str, Any]         =     ret
              return ret






def 							A(    snake_case_ = 60		,  snake_case_ = 1000000						):
       """simple docstring"""





       return sum(1 for i in range(1		,  snake_case_						) if chain_length(snake_case_						) == num_terms						)


if __name__ == "__main__":
  print(F"{solution() = }")












'''simple docstring'''






import tempfile
import unittest

from transformers import DPRConfig, is_torch_available
from transformers.testing_utils import require_torch, slow, torch_device

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
				import torch

				from transformers import DPRContextEncoder, DPRQuestionEncoder, DPRReader, DPRReaderTokenizer
				from transformers.models.dpr.modeling_dpr import (
				    DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST,
				    DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST,
				    DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST,
				)



class    A						:




				'''simple docstring'''





				def __init__(self					,    _UpperCAmelCase					,    _UpperCAmelCase=1_3					,    _UpperCAmelCase=7					,    _UpperCAmelCase=False					,    _UpperCAmelCase=True					,    _UpperCAmelCase=True					,    _UpperCAmelCase=True					,    _UpperCAmelCase=9_9					,    _UpperCAmelCase=3_2					,    _UpperCAmelCase=5					,    _UpperCAmelCase=4					,    _UpperCAmelCase=3_7					,    _UpperCAmelCase="gelu"					,    _UpperCAmelCase=0.1					,    _UpperCAmelCase=0.1					,    _UpperCAmelCase=5_1_2					,    _UpperCAmelCase=1_6					,    _UpperCAmelCase=2					,    _UpperCAmelCase=0.02					,    _UpperCAmelCase=3					,    _UpperCAmelCase=4					,    _UpperCAmelCase=None					,    _UpperCAmelCase=0					,    )      ->			List[Any]:
							__UpperCamelCase :     List[str]										=  parent
							__UpperCamelCase :     Optional[int]										=  batch_size
							__UpperCamelCase :     Union[str, Any]										=  seq_length
							__UpperCamelCase :     List[Any]										=  is_training
							__UpperCamelCase :     Union[str, Any]										=  use_input_mask
							__UpperCamelCase :     int										=  use_token_type_ids
							__UpperCamelCase :     Any										=  use_labels
							__UpperCamelCase :     Union[str, Any]										=  vocab_size
							__UpperCamelCase :     Any										=  hidden_size
							__UpperCamelCase :     Dict										=  num_hidden_layers
							__UpperCamelCase :     List[Any]										=  num_attention_heads
							__UpperCamelCase :     Union[str, Any]										=  intermediate_size
							__UpperCamelCase :     Tuple										=  hidden_act
							__UpperCamelCase :     int										=  hidden_dropout_prob
							__UpperCamelCase :     Optional[Any]										=  attention_probs_dropout_prob
							__UpperCamelCase :     List[str]										=  max_position_embeddings
							__UpperCamelCase :     str										=  type_vocab_size
							__UpperCamelCase :     str										=  type_sequence_label_size
							__UpperCamelCase :     List[str]										=  initializer_range
							__UpperCamelCase :     List[str]										=  num_labels
							__UpperCamelCase :     Any										=  num_choices
							__UpperCamelCase :     List[Any]										=  scope
							__UpperCamelCase :     Tuple										=  projection_dim
				def 			a_			(self     )      ->			Any:
							__UpperCamelCase :     str										=  ids_tensor([self.batch_size, self.seq_length]					,    self.vocab_size     )

							__UpperCamelCase :     Dict										=  None
							if self.use_input_mask:
										__UpperCamelCase :     List[str]										=  random_attention_mask([self.batch_size, self.seq_length]     )

							__UpperCamelCase :     Tuple										=  None
							if self.use_token_type_ids:
										__UpperCamelCase :     Optional[int]										=  ids_tensor([self.batch_size, self.seq_length]					,    self.type_vocab_size     )

							__UpperCamelCase :     List[Any]										=  None
							__UpperCamelCase :     Optional[Any]										=  None
							__UpperCamelCase :     List[str]										=  None
							if self.use_labels:
										__UpperCamelCase :     Dict										=  ids_tensor([self.batch_size]					,    self.type_sequence_label_size     )
										__UpperCamelCase :     Any										=  ids_tensor([self.batch_size, self.seq_length]					,    self.num_labels     )
										__UpperCamelCase :     str										=  ids_tensor([self.batch_size]					,    self.num_choices     )

							__UpperCamelCase :     Optional[int]										=  self.get_config()

							return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels
				def 			a_			(self     )      ->			Optional[Any]:
							return DPRConfig(
							    projection_dim=self.projection_dim					,    vocab_size=self.vocab_size					,    hidden_size=self.hidden_size					,    num_hidden_layers=self.num_hidden_layers					,    num_attention_heads=self.num_attention_heads					,    intermediate_size=self.intermediate_size					,    hidden_act=self.hidden_act					,    hidden_dropout_prob=self.hidden_dropout_prob					,    attention_probs_dropout_prob=self.attention_probs_dropout_prob					,    max_position_embeddings=self.max_position_embeddings					,    type_vocab_size=self.type_vocab_size					,    initializer_range=self.initializer_range					,    )
				def 			a_			(self					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase     )      ->			str:
							__UpperCamelCase :     Optional[int]										=  DPRContextEncoder(config=_UpperCAmelCase     )
							model.to(_UpperCAmelCase     )
							model.eval()
							__UpperCamelCase :     Optional[int]										=  model(_UpperCAmelCase					,    attention_mask=_UpperCAmelCase					,    token_type_ids=_UpperCAmelCase     )
							__UpperCamelCase :     Optional[int]										=  model(_UpperCAmelCase					,    token_type_ids=_UpperCAmelCase     )
							__UpperCamelCase :     int										=  model(_UpperCAmelCase     )
							self.parent.assertEqual(result.pooler_output.shape					,    (self.batch_size, self.projection_dim or self.hidden_size)     )
				def 			a_			(self					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase     )      ->			Optional[int]:
							__UpperCamelCase :     int										=  DPRQuestionEncoder(config=_UpperCAmelCase     )
							model.to(_UpperCAmelCase     )
							model.eval()
							__UpperCamelCase :     Optional[int]										=  model(_UpperCAmelCase					,    attention_mask=_UpperCAmelCase					,    token_type_ids=_UpperCAmelCase     )
							__UpperCamelCase :     List[str]										=  model(_UpperCAmelCase					,    token_type_ids=_UpperCAmelCase     )
							__UpperCamelCase :     Optional[Any]										=  model(_UpperCAmelCase     )
							self.parent.assertEqual(result.pooler_output.shape					,    (self.batch_size, self.projection_dim or self.hidden_size)     )
				def 			a_			(self					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase     )      ->			str:
							__UpperCamelCase :     Optional[int]										=  DPRReader(config=_UpperCAmelCase     )
							model.to(_UpperCAmelCase     )
							model.eval()
							__UpperCamelCase :     Optional[Any]										=  model(
							    _UpperCAmelCase					,    attention_mask=_UpperCAmelCase					,    )

							self.parent.assertEqual(result.start_logits.shape					,    (self.batch_size, self.seq_length)     )
							self.parent.assertEqual(result.end_logits.shape					,    (self.batch_size, self.seq_length)     )
							self.parent.assertEqual(result.relevance_logits.shape					,    (self.batch_size,)     )





				def 			a_			(self     )      ->			List[Any]:
							__UpperCamelCase :     Tuple										=  self.prepare_config_and_inputs()
							(
							    (
							    __UpperCamelCase
							)						,   (
							    __UpperCamelCase
							)						,   (
							    __UpperCamelCase
							)						,   (
							    __UpperCamelCase
							)						,   (
							    __UpperCamelCase
							)						,   (
							    __UpperCamelCase
							)						,   (
							    __UpperCamelCase
							)						,   
							) :     Optional[int]										=  config_and_inputs
							__UpperCamelCase :     Dict										=  {"input_ids": input_ids}
							return config, inputs_dict







@require_torch
class    A						(					SCREAMING_SNAKE_CASE__     ,				SCREAMING_SNAKE_CASE__     ,				unittest.TestCase						):




				'''simple docstring'''





				A       =							(
				    (
				        DPRContextEncoder,
				        DPRQuestionEncoder,
				        DPRReader,
				    )
				    if is_torch_available()
				    else ()
				)
				A       =							{"feature-extraction": DPRQuestionEncoder} if is_torch_available() else {}

				A       =							False
				A       =							False  # why?
				A       =							False
				A       =							False
				def 			a_			(self     )      ->			Union[str, Any]:
							__UpperCamelCase :     Dict										=  DPRModelTester(self     )
							__UpperCamelCase :     Tuple										=  ConfigTester(self					,    config_class=_UpperCAmelCase					,    hidden_size=3_7     )
				def 			a_			(self     )      ->			List[str]:
							self.config_tester.run_common_tests()
				def 			a_			(self     )      ->			Optional[int]:
							__UpperCamelCase :     List[Any]										=  self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_context_encoder(*_UpperCAmelCase     )
				def 			a_			(self     )      ->			str:
							__UpperCamelCase :     int										=  self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_question_encoder(*_UpperCAmelCase     )
				def 			a_			(self     )      ->			Any:
							__UpperCamelCase :     List[Any]										=  self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_reader(*_UpperCAmelCase     )
				def 			a_			(self     )      ->			Optional[Any]:
							__UpperCamelCase :     List[Any]										=  self.model_tester.prepare_config_and_inputs()[0]

							__UpperCamelCase :     Union[str, Any]										=  DPRQuestionEncoder(config=_UpperCAmelCase     )
							model.to(_UpperCAmelCase     )
							model.eval()

							with tempfile.TemporaryDirectory() as tmp_dirname:
										model.save_pretrained(_UpperCAmelCase     )
										__UpperCamelCase :     Tuple										=  DPRQuestionEncoder.from_pretrained(_UpperCAmelCase					,    projection_dim=5_1_2     )

							self.assertIsNotNone(_UpperCAmelCase     )





				@slow
				def 			a_			(self     )      ->			Optional[Any]:
							for model_name in DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
										__UpperCamelCase :     Union[str, Any]										=  DPRContextEncoder.from_pretrained(_UpperCAmelCase     )
										self.assertIsNotNone(_UpperCAmelCase     )

							for model_name in DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
										__UpperCamelCase :     Tuple										=  DPRContextEncoder.from_pretrained(_UpperCAmelCase     )
										self.assertIsNotNone(_UpperCAmelCase     )

							for model_name in DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
										__UpperCamelCase :     Union[str, Any]										=  DPRQuestionEncoder.from_pretrained(_UpperCAmelCase     )
										self.assertIsNotNone(_UpperCAmelCase     )

							for model_name in DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
										__UpperCamelCase :     Optional[int]										=  DPRReader.from_pretrained(_UpperCAmelCase     )
										self.assertIsNotNone(_UpperCAmelCase     )







@require_torch
class    A						(					unittest.TestCase						):




				'''simple docstring'''





				@slow
				def 			a_			(self     )      ->			Dict:
							__UpperCamelCase :     int										=  DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base"					,    return_dict=_UpperCAmelCase     )
							model.to(_UpperCAmelCase     )

							__UpperCamelCase :     Optional[int]										=  torch.tensor(
							    [[1_0_1, 7_5_9_2, 1_0_1_0, 2_0_0_3, 2_0_2_6, 3_8_9_9, 1_0_1_4_0, 1_0_2_9, 1_0_2]]					,    dtype=torch.long					,    device=_UpperCAmelCase     )  # [CLS] hello, is my dog cute? [SEP]
							__UpperCamelCase :     Dict										=  model(_UpperCAmelCase     )[0]  # embedding shape = (1, 768)
							# compare the actual values for a slice.
							__UpperCamelCase :     Union[str, Any]										=  torch.tensor(
							    [
							        [
							            0.03_236_253,
							            0.12_753_335,
							            0.16_818_509,
							            0.00_279_786,
							            0.3_896_933,
							            0.24_264_945,
							            0.2_178_971,
							            -0.02_335_227,
							            -0.08_481_959,
							            -0.14_324_117,
							        ]
							    ]					,    dtype=torch.float					,    device=_UpperCAmelCase					,    )
							self.assertTrue(torch.allclose(output[:, :1_0]					,    _UpperCAmelCase					,    atol=1E-4     )     )





				@slow
				def 			a_			(self     )      ->			List[str]:
							__UpperCamelCase :     Any										=  DPRReaderTokenizer.from_pretrained("facebook/dpr-reader-single-nq-base"     )
							__UpperCamelCase :     str										=  DPRReader.from_pretrained("facebook/dpr-reader-single-nq-base"     )
							model.to(_UpperCAmelCase     )

							__UpperCamelCase :     Optional[int]										=  tokenizer(
							    questions="What is love ?"					,    titles="Haddaway"					,    texts="What Is Love is a song recorded by the artist Haddaway"					,    padding=_UpperCAmelCase					,    return_tensors="pt"					,    )
							encoded_inputs.to(_UpperCAmelCase     )

							__UpperCamelCase :     int										=  model(**_UpperCAmelCase     )

							# compare the actual values for a slice.
							__UpperCamelCase :     Dict										=  torch.tensor(
							    [[-10.3_005, -10.7_765, -11.4_872, -11.6_841, -11.9_312, -10.3_002, -9.8_544, -11.7_378, -12.0_821, -10.2_975]]					,    dtype=torch.float					,    device=_UpperCAmelCase					,    )

							__UpperCamelCase :     Optional[Any]										=  torch.tensor(
							    [[-11.0_684, -11.7_041, -11.5_397, -10.3_465, -10.8_791, -6.8_443, -11.9_959, -11.0_364, -10.0_096, -6.8_405]]					,    dtype=torch.float					,    device=_UpperCAmelCase					,    )
							self.assertTrue(torch.allclose(outputs.start_logits[:, :1_0]					,    _UpperCAmelCase					,    atol=1E-4     )     )
							self.assertTrue(torch.allclose(outputs.end_logits[:, :1_0]					,    _UpperCAmelCase					,    atol=1E-4     )     )



