


import os
import unicodedata
from shutil import copyfile
from typing import Any, Dict, List, Optional, Tuple

import sentencepiece as spm

from ...tokenization_utils import AddedToken, PreTrainedTokenizer
from ...utils import logging


A			:						Optional[Any]        =  logging.get_logger(__name__)
A			:						Optional[Any]        =  {'vocab_file': 'spiece.model'}

A			:						Union[str, Any]        =  {
    'vocab_file': {
        'albert-base-v1': 'https://huggingface.co/albert-base-v1/resolve/main/spiece.model',
        'albert-large-v1': 'https://huggingface.co/albert-large-v1/resolve/main/spiece.model',
        'albert-xlarge-v1': 'https://huggingface.co/albert-xlarge-v1/resolve/main/spiece.model',
        'albert-xxlarge-v1': 'https://huggingface.co/albert-xxlarge-v1/resolve/main/spiece.model',
        'albert-base-v2': 'https://huggingface.co/albert-base-v2/resolve/main/spiece.model',
        'albert-large-v2': 'https://huggingface.co/albert-large-v2/resolve/main/spiece.model',
        'albert-xlarge-v2': 'https://huggingface.co/albert-xlarge-v2/resolve/main/spiece.model',
        'albert-xxlarge-v2': 'https://huggingface.co/albert-xxlarge-v2/resolve/main/spiece.model',
    }
}

A			:						Tuple        =  {
    'albert-base-v1': 5_1_2,
    'albert-large-v1': 5_1_2,
    'albert-xlarge-v1': 5_1_2,
    'albert-xxlarge-v1': 5_1_2,
    'albert-base-v2': 5_1_2,
    'albert-large-v2': 5_1_2,
    'albert-xlarge-v2': 5_1_2,
    'albert-xxlarge-v2': 5_1_2,
}

A			:						Dict        =  '▁'



class 				A       (			UpperCamelCase_				):
					'''simple docstring'''






					A__     =					VOCAB_FILES_NAMES
					A__     =					PRETRAINED_VOCAB_FILES_MAP
					A__     =					PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES

					def __init__(self       :		List[Any] ,   _UpperCAmelCase       :		List[Any] ,   _UpperCAmelCase       :		List[Any]=True ,   _UpperCAmelCase       :		Union[str, Any]=True ,   _UpperCAmelCase       :		Dict=False ,   _UpperCAmelCase       :		Union[str, Any]="[CLS]" ,   _UpperCAmelCase       :		Any="[SEP]" ,   _UpperCAmelCase       :		List[str]="<unk>" ,   _UpperCAmelCase       :		Dict="[SEP]" ,   _UpperCAmelCase       :		Optional[Any]="<pad>" ,   _UpperCAmelCase       :		int="[CLS]" ,   _UpperCAmelCase       :		Optional[Any]="[MASK]" ,   _UpperCAmelCase       :		Optional[Dict[str, Any]] = None ,   **_UpperCAmelCase       :		Dict ,   )		->  Any:




							"""simple docstring"""


							lowercase__	     =						(
							    AddedToken(a__ ,   lstrip=a__ ,   rstrip=a__ ,   normalized=a__						)
							    if isinstance(a__ ,   a__						)
							    else mask_token
							)

							lowercase__	     =						{} if sp_model_kwargs is None else sp_model_kwargs

							super().__init__(
							    do_lower_case=a__ ,   remove_space=a__ ,   keep_accents=a__ ,   bos_token=a__ ,   eos_token=a__ ,   unk_token=a__ ,   sep_token=a__ ,   pad_token=a__ ,   cls_token=a__ ,   mask_token=a__ ,   sp_model_kwargs=self.sp_model_kwargs ,   **a__ ,   )

							lowercase__	     =						do_lower_case
							lowercase__	     =						remove_space
							lowercase__	     =						keep_accents
							lowercase__	     =						vocab_file

							lowercase__	     =						spm.SentencePieceProcessor(**self.sp_model_kwargs						)
							self.sp_model.Load(a__						)

					@property
					def     lowerCamelCase__	(self       :		List[Any]						)		->  List[str]:




							"""simple docstring"""


							return len(self.sp_model						)

					def     lowerCamelCase__	(self       :		List[Any]						)		->  List[Any]:




							"""simple docstring"""


							lowercase__	     =						{self.convert_ids_to_tokens(a__						): i for i in range(self.vocab_size						)}
							vocab.update(self.added_tokens_encoder						)
							return vocab

					def __getstate__(self       :		List[str]						)		->  List[Any]:




							"""simple docstring"""


							lowercase__	     =						self.__dict__.copy()
							lowercase__	     =						None
							return state

					def __setstate__(self       :		str ,   _UpperCAmelCase       :		Tuple						)		->  Union[str, Any]:




							"""simple docstring"""


							lowercase__	     =						d

							# for backward compatibility
							if not hasattr(self ,   """sp_model_kwargs"""						):
									lowercase__	     =						{}

							lowercase__	     =						spm.SentencePieceProcessor(**self.sp_model_kwargs						)
							self.sp_model.Load(self.vocab_file						)

					def     lowerCamelCase__	(self       :		List[Any] ,   _UpperCAmelCase       :		List[Any]						)		->  str:




							"""simple docstring"""


							if self.remove_space:
									lowercase__	     =						" ".join(inputs.strip().split()						)
							else:
									lowercase__	     =						inputs
							lowercase__	     =						outputs.replace("""``""" ,   """\""""						).replace("""''""" ,   """\""""						)

							if not self.keep_accents:
									lowercase__	     =						unicodedata.normalize("""NFKD""" ,   a__						)
									lowercase__	     =						"".join([c for c in outputs if not unicodedata.combining(a__						)]						)
							if self.do_lower_case:
									lowercase__	     =						outputs.lower()

							return outputs

					def     lowerCamelCase__	(self       :		Optional[Any] ,   _UpperCAmelCase       :		str						)		->  Union[str, Any]:




							"""simple docstring"""


							lowercase__	     =						self.preprocess_text(a__						)
							lowercase__	     =						self.sp_model.encode(a__ ,   out_type=a__						)
							lowercase__	     =						[]
							for piece in pieces:
									if len(a__						) > 1 and piece[-1] == str(""","""						) and piece[-2].isdigit():
											lowercase__	     =						self.sp_model.EncodeAsPieces(piece[:-1].replace(a__ ,   """"""						)						)
											if piece[0] != SPIECE_UNDERLINE and cur_pieces[0][0] == SPIECE_UNDERLINE:
													if len(cur_pieces[0]						) == 1:
															lowercase__	     =						cur_pieces[1:]
													else:
															lowercase__	     =						cur_pieces[0][1:]
											cur_pieces.append(piece[-1]						)
											new_pieces.extend(a__						)
									else:
											new_pieces.append(a__						)

							return new_pieces

					def     lowerCamelCase__	(self       :		Union[str, Any] ,   _UpperCAmelCase       :		Dict						)		->  Any:




							"""simple docstring"""


							return self.sp_model.PieceToId(a__						)

					def     lowerCamelCase__	(self       :		Optional[Any] ,   _UpperCAmelCase       :		Dict						)		->  Optional[Any]:




							"""simple docstring"""


							return self.sp_model.IdToPiece(a__						)

					def     lowerCamelCase__	(self       :		int ,   _UpperCAmelCase       :		str						)		->  List[str]:




							"""simple docstring"""


							lowercase__	     =						[]
							lowercase__	     =						""
							lowercase__	     =						False
							for token in tokens:
									# make sure that special tokens are not decoded using sentencepiece model
									if token in self.all_special_tokens:
											if not prev_is_special:
													out_string += " "
											out_string += self.sp_model.decode(a__						) + token
											lowercase__	     =						True
											lowercase__	     =						[]
									else:
											current_sub_tokens.append(a__						)
											lowercase__	     =						False
							out_string += self.sp_model.decode(a__						)
							return out_string.strip()

					def     lowerCamelCase__	(self       :		Dict ,   _UpperCAmelCase       :		List[int] ,   _UpperCAmelCase       :		Optional[List[int]] = None						)		->  str:




							"""simple docstring"""


							lowercase__	     =						[self.sep_token_id]
							lowercase__	     =						[self.cls_token_id]
							if token_ids_a is None:
									return cls + token_ids_a + sep
							return cls + token_ids_a + sep + token_ids_a + sep

					def     lowerCamelCase__	(self       :		Tuple ,   _UpperCAmelCase       :		List[int] ,   _UpperCAmelCase       :		Optional[List[int]] = None ,   _UpperCAmelCase       :		bool = False						)		->  Any:




							"""simple docstring"""


							if already_has_special_tokens:
									return super().get_special_tokens_mask(
									    token_ids_a=a__ ,   token_ids_a=a__ ,   already_has_special_tokens=a__						)

							if token_ids_a is not None:
									return [1] + ([0] * len(a__						)) + [1] + ([0] * len(a__						)) + [1]
							return [1] + ([0] * len(a__						)) + [1]

					def     lowerCamelCase__	(self       :		Dict ,   _UpperCAmelCase       :		List[int] ,   _UpperCAmelCase       :		Optional[List[int]] = None						)		->  Tuple:




							"""simple docstring"""


							lowercase__	     =						[self.sep_token_id]
							lowercase__	     =						[self.cls_token_id]

							if token_ids_a is None:
									return len(cls + token_ids_a + sep						) * [0]
							return len(cls + token_ids_a + sep						) * [0] + len(token_ids_a + sep						) * [1]


					def     lowerCamelCase__	(self       :		Dict ,   _UpperCAmelCase       :		str ,   _UpperCAmelCase       :		Optional[str] = None						)		->  Any:




							"""simple docstring"""


							if not os.path.isdir(a__						):
									logger.error(f'''Vocabulary path ({save_directory}) should be a directory'''						)
									return
							lowercase__	     =						os.path.join(
							    a__ ,   (filename_prefix + """-""" if filename_prefix else """""") + VOCAB_FILES_NAMES["""vocab_file"""]						)

							if os.path.abspath(self.vocab_file						) != os.path.abspath(a__						) and os.path.isfile(self.vocab_file						):
									copyfile(self.vocab_file ,   a__						)
							elif not os.path.isfile(self.vocab_file						):
									with open(a__ ,   """wb"""						) as fi:
											lowercase__	     =						self.sp_model.serialized_model_proto()
											fi.write(a__						)

							return (out_vocab_file,)



'''simple docstring'''

from math import factorial

snake_case									=    {str(digit): factorial(digit) for digit in range(10)}


def        UpperCAmelCase_ (  lowerCamelCase_			):







 """simple docstring"""


 if not isinstance(lowerCamelCase_      ,			lowerCamelCase_			):
  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(lowerCamelCase_			)			)


def        UpperCAmelCase_ (  lowerCamelCase_ = 6_0      ,			lowerCamelCase_ = 1_0_0_0_0_0_0			):







 """simple docstring"""


 if not isinstance(lowerCamelCase_      ,			lowerCamelCase_			) or not isinstance(lowerCamelCase_      ,			lowerCamelCase_			):
  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
 lowerCAmelCase__     :   str     		=	0
 # the cached sizes of the previous chains
 lowerCAmelCase__     :   dict[int, int]     		=	{}

 for start_chain_element in range(1      ,			lowerCamelCase_			):
  # The temporary set will contain the elements of the chain
  lowerCAmelCase__     :   Any     		=	set()
  lowerCAmelCase__     :   int     		=	0

  # Stop computing the chain when you find a cached size, a repeating item or the
  # length is greater then the desired one.
  lowerCAmelCase__     :   Dict     		=	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(lowerCamelCase_			)
   chain_set_length += 1
   lowerCAmelCase__     :   Dict     		=	digit_factorial_sum(lowerCamelCase_			)

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

  lowerCAmelCase__     :   Optional[Any]     		=	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()}')





