



'''simple docstring'''

import json
from typing import Iterator, List, Union

from tokenizers import AddedToken, Regex, Tokenizer, decoders, normalizers, pre_tokenizers, trainers
from tokenizers.implementations.base_tokenizer import BaseTokenizer
from tokenizers.models import Unigram
from tokenizers.processors import TemplateProcessing

class      __magic_name__						(   _UpperCamelCase       ):







							def __init__(							self :	List[Any]     ,_UpperCAmelCase :	str = "▁"     ,_UpperCAmelCase :	bool = True     ,_UpperCAmelCase :	Union[str, AddedToken] = "<unk>"     ,_UpperCAmelCase :	Union[str, AddedToken] = "</s>"     ,_UpperCAmelCase :	Union[str, AddedToken] = "<pad>"     ,):
									_a					:				Union[str, Any]				=							{
									    'pad': {'id': 0, 'token': pad_token},
									    'eos': {'id': 1, 'token': eos_token},
									    'unk': {'id': 2, 'token': unk_token},
									}

									_a					:				Optional[Any]				=							[None] * len(self.special_tokens		)
									for token_dict in self.special_tokens.values():
											_a					:				Optional[Any]				=							token_dict['token']

									_a					:				Optional[int]				=							Tokenizer(Unigram()		)

									_a					:				List[Any]				=							normalizers.Sequence(
									    [
									        normalizers.Nmt(),
									        normalizers.NFKC(),
									        normalizers.Replace(Regex(' {2,}'		)     ,' '		),
									        normalizers.Lowercase(),
									    ]		)
									_a					:				Optional[int]				=							pre_tokenizers.Sequence(
									    [
									        pre_tokenizers.Metaspace(replacement=_UpperCAmelCase     ,add_prefix_space=_UpperCAmelCase		),
									        pre_tokenizers.Digits(individual_digits=_UpperCAmelCase		),
									        pre_tokenizers.Punctuation(),
									    ]		)
									_a					:				int				=							decoders.Metaspace(replacement=_UpperCAmelCase     ,add_prefix_space=_UpperCAmelCase		)

									_a					:				Optional[Any]				=							TemplateProcessing(
									    single=F"""$A {self.special_tokens['eos']['token']}"""     ,special_tokens=[(self.special_tokens['eos']['token'], self.special_tokens['eos']['id'])]     ,)

									_a					:				str				=							{
									    'model': 'SentencePieceUnigram',
									    'replacement': replacement,
									    'add_prefix_space': add_prefix_space,
									}

									super().__init__(_UpperCAmelCase     ,_UpperCAmelCase		)







							def 							__lowercase      (							self :	str     ,_UpperCAmelCase :	Union[str, List[str]]     ,_UpperCAmelCase :	int = 8000     ,_UpperCAmelCase :	bool = True     ,):
									_a					:				int				=							trainers.UnigramTrainer(
									    vocab_size=_UpperCAmelCase     ,special_tokens=self.special_tokens_list     ,show_progress=_UpperCAmelCase     ,)

									if isinstance(_UpperCAmelCase     ,_UpperCAmelCase		):
											_a					:				Union[str, Any]				=							[files]
									self._tokenizer.train(_UpperCAmelCase     ,trainer=_UpperCAmelCase		)

									self.add_unk_id()







							def 							__lowercase      (							self :	Optional[Any]     ,_UpperCAmelCase :	Union[Iterator[str], Iterator[Iterator[str]]]     ,_UpperCAmelCase :	int = 8000     ,_UpperCAmelCase :	bool = True     ,):
									_a					:				Tuple				=							trainers.UnigramTrainer(
									    vocab_size=_UpperCAmelCase     ,special_tokens=self.special_tokens_list     ,show_progress=_UpperCAmelCase     ,)

									self._tokenizer.train_from_iterator(_UpperCAmelCase     ,trainer=_UpperCAmelCase		)

									self.add_unk_id()







							def 							__lowercase      (							self :	Any		):
									_a					:				Optional[Any]				=							json.loads(self._tokenizer.to_str()		)

									_a					:				Any				=							self.special_tokens['unk']['id']

									_a					:				int				=							Tokenizer.from_str(json.dumps(_UpperCAmelCase		)		)









'''simple docstring'''

__lowerCAmelCase						      =       range(2, 20 + 1)
__lowerCAmelCase						      =       [10**k for k in range(ks[-1] + 1)]
__lowerCAmelCase						      =       {}



def 					__lowerCamelCase					(				lowerCAmelCase_						,      lowerCAmelCase_						,      lowerCAmelCase_						,      lowerCAmelCase_  )      ->				Optional[Any]:
		_a					:				Optional[int]				=							sum(a_i[j] for j in range(lowerCAmelCase_						,      len(lowerCAmelCase_  )  )  )
		_a					:				List[str]				=							sum(a_i[j] * base[j] for j in range(min(len(lowerCAmelCase_  )						,      lowerCAmelCase_  )  )  )

		_a	, _a					:				Any				=							0, 0
		_a					:				Any				=							n - i

		_a					:				List[Any]				=							memo.get(lowerCAmelCase_  )

		if sub_memo is not None:
				_a					:				Tuple				=							sub_memo.get(lowerCAmelCase_  )

				if jumps is not None and len(lowerCAmelCase_  ) > 0:
						# find and make the largest jump without going over
						_a					:				Any				=							-1
						for _k in range(len(lowerCAmelCase_  ) - 1						,      -1						,      -1  ):
								if jumps[_k][2] <= k and jumps[_k][1] <= max_dn:
										_a					:				Any				=							_k
										break

						if max_jump >= 0:
								_a	, _a	, _a					:				Tuple				=							jumps[max_jump]
								# since the difference between jumps is cached, add c
								_a					:				Union[str, Any]				=							diff + c
								for j in range(min(lowerCAmelCase_						,      len(lowerCAmelCase_  )  )  ):
										_a	, _a					:				Dict				=							divmod(lowerCAmelCase_						,      10  )
								if new_c > 0:
										add(lowerCAmelCase_						,      lowerCAmelCase_						,      lowerCAmelCase_  )

				else:
						_a					:				Tuple				=							[]
		else:
				_a					:				Any				=							{c: []}
				_a					:				Optional[Any]				=							sub_memo

		if dn >= max_dn or c + diff >= base[k]:
				return diff, dn

		if k > ks[0]:
				while True:
						# keep doing smaller jumps
						_a	, _a					:				Dict				=							next_term(lowerCAmelCase_						,      k - 1						,      i + dn						,      lowerCAmelCase_  )
						diff += _diff
						dn += terms_jumped

						if dn >= max_dn or c + diff >= base[k]:
								break
		else:
				# would be too small a jump, just compute sequential terms instead
				_a	, _a					:				Any				=							compute(lowerCAmelCase_						,      lowerCAmelCase_						,      i + dn						,      lowerCAmelCase_  )
				diff += _diff
				dn += terms_jumped

		_a					:				Tuple				=							sub_memo[c]

		# keep jumps sorted by # of terms skipped
		_a					:				Any				=							0
		while j < len(lowerCAmelCase_  ):
				if jumps[j][1] > dn:
						break
				j += 1

		# cache the jump for this value digitsum(b) and c
		sub_memo[c].insert(lowerCAmelCase_						,      (diff, dn, k)  )
		return (diff, dn)



def 					__lowerCamelCase					(				lowerCAmelCase_						,      lowerCAmelCase_						,      lowerCAmelCase_						,      lowerCAmelCase_  )      ->				str:
		if i >= n:
				return 0, i
		if k > len(lowerCAmelCase_  ):
				a_i.extend([0 for _ in range(k - len(lowerCAmelCase_  )  )]  )

		# note: a_i -> b * 10^k + c
		# ds_b -> digitsum(b)
		# ds_c -> digitsum(c)
		_a					:				Any				=							i
		_a	, _a	, _a					:				Optional[int]				=							0, 0, 0
		for j in range(len(lowerCAmelCase_  )  ):
				if j >= k:
						ds_b += a_i[j]
				else:
						ds_c += a_i[j]

		while i < n:
				i += 1
				_a					:				Any				=							ds_c + ds_b
				diff += addend
				_a					:				int				=							0
				for j in range(lowerCAmelCase_  ):
						_a					:				Optional[Any]				=							a_i[j] + addend
						_a	, _a					:				Tuple				=							divmod(lowerCAmelCase_						,      10  )

						ds_c += a_i[j]

				if addend > 0:
						break

		if addend > 0:
				add(lowerCAmelCase_						,      lowerCAmelCase_						,      lowerCAmelCase_  )
		return diff, i - start_i



def 					__lowerCamelCase					(				lowerCAmelCase_						,      lowerCAmelCase_						,      lowerCAmelCase_  )      ->				int:
		for j in range(lowerCAmelCase_						,      len(lowerCAmelCase_  )  ):
				_a					:				Optional[Any]				=							digits[j] + addend
				if s >= 10:
						_a	, _a					:				List[str]				=							divmod(lowerCAmelCase_						,      10  )
						_a					:				List[str]				=							addend // 10 + quotient
				else:
						_a					:				Optional[Any]				=							s
						_a					:				Optional[Any]				=							addend // 10

				if addend == 0:
						break

		while addend > 0:
				_a	, _a					:				List[str]				=							divmod(lowerCAmelCase_						,      10  )
				digits.append(lowerCAmelCase_  )



def 					__lowerCamelCase					(				lowerCAmelCase_ = 10**15  )      ->				int:
		_a					:				Dict				=							[1]
		_a					:				int				=							1
		_a					:				Tuple				=							0
		while True:
				_a	, _a					:				str				=							next_term(lowerCAmelCase_						,      20						,      i + dn						,      lowerCAmelCase_  )
				dn += terms_jumped
				if dn == n - i:
						break

		_a					:				Union[str, Any]				=							0
		for j in range(len(lowerCAmelCase_  )  ):
				a_n += digits[j] * 10**j
		return a_n


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




