





from typing import Dict, List, Optional, Union

import numpy as np

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import (
    center_crop,
    get_resize_output_image_size,
    normalize,
    rescale,
    resize,
    to_channel_dimension_format,
)
from ...image_utils import (
    IMAGENET_DEFAULT_MEAN,
    IMAGENET_DEFAULT_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    is_batched,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, logging


UpperCamelCase__   : str					  = logging.get_logger(__name__)







class   _UpperCamelCase  (       A_  ):







					'''simple docstring'''

					lowerCamelCase     :     int			    =       ['pixel_values']





					def __init__(						self    :  List[Any] ,					__lowercase    :  bool = True ,					__lowercase    :  Optional[Dict[str, int]] = None ,					__lowercase    :  PILImageResampling = PILImageResampling.BICUBIC ,					__lowercase    :  bool = True ,					__lowercase    :  bool = True ,					__lowercase    :  Union[int, float] = 1 / 2_55 ,					__lowercase    :  Dict[str, int] = None ,					__lowercase    :  bool = True ,					__lowercase    :  Optional[Union[float, List[float]]] = None ,					__lowercase    :  Optional[Union[float, List[float]]] = None ,					**__lowercase    :  int ,					):






						'''simple docstring'''







						super().__init__(**__lowercase		)
						UpperCAmelCase_								=     size if size is not None else {"""height""": 2_24, """width""": 2_24}
						UpperCAmelCase_								=     get_size_dict(__lowercase		)
						UpperCAmelCase_								=     crop_size if crop_size is not None else {"""height""": 2_24, """width""": 2_24}
						UpperCAmelCase_								=     get_size_dict(__lowercase ,					default_to_square=__lowercase ,					param_name="""crop_size"""		)

						UpperCAmelCase_								=     do_resize
						UpperCAmelCase_								=     do_rescale
						UpperCAmelCase_								=     do_normalize
						UpperCAmelCase_								=     do_center_crop
						UpperCAmelCase_								=     crop_size
						UpperCAmelCase_								=     size
						UpperCAmelCase_								=     resample
						UpperCAmelCase_								=     rescale_factor
						UpperCAmelCase_								=     image_mean if image_mean is not None else IMAGENET_DEFAULT_MEAN
						UpperCAmelCase_								=     image_std if image_std is not None else IMAGENET_DEFAULT_STD





					def        SCREAMING_SNAKE_CASE							(						self    :  int ,					__lowercase    :  np.ndarray ,					__lowercase    :  Dict[str, int] ,					__lowercase    :  PILImageResampling = PILImageResampling.BILINEAR ,					__lowercase    :  Optional[Union[str, ChannelDimension]] = None ,					**__lowercase    :  Tuple ,					):






						'''simple docstring'''







						UpperCAmelCase_								=     get_size_dict(__lowercase		)

						if "shortest_edge" in size:
							UpperCAmelCase_								=     get_resize_output_image_size(__lowercase ,					size=size["""shortest_edge"""] ,					default_to_square=__lowercase		)
							# size = get_resize_output_image_size(image, size["shortest_edge"], size["longest_edge"])
						elif "height" in size and "width" in size:
							UpperCAmelCase_								=     (size["""height"""], size["""width"""])
						else:
							raise ValueError(F"""Size must contain 'height' and 'width' keys or 'shortest_edge' key. Got {size.keys()}"""		)
						return resize(__lowercase ,					size=__lowercase ,					resample=__lowercase ,					data_format=__lowercase ,					**__lowercase		)





					def        SCREAMING_SNAKE_CASE							(						self    :  List[str] ,					__lowercase    :  np.ndarray ,					__lowercase    :  Dict[str, int] ,					__lowercase    :  Optional[Union[str, ChannelDimension]] = None ,					**__lowercase    :  List[Any] ,					):






						'''simple docstring'''







						UpperCAmelCase_								=     get_size_dict(__lowercase		)
						if "height" not in size or "width" not in size:
							raise ValueError(F"""The `size` parameter must contain the keys (height, width). Got {size.keys()}"""		)
						return center_crop(__lowercase ,					size=(size["""height"""], size["""width"""]) ,					data_format=__lowercase ,					**__lowercase		)





					def        SCREAMING_SNAKE_CASE							(						self    :  List[str] ,					__lowercase    :  np.ndarray ,					__lowercase    :  float ,					__lowercase    :  Optional[Union[str, ChannelDimension]] = None ,					**__lowercase    :  Tuple		):






						'''simple docstring'''







						return rescale(__lowercase ,					scale=__lowercase ,					data_format=__lowercase ,					**__lowercase		)





					def        SCREAMING_SNAKE_CASE							(						self    :  List[Any] ,					__lowercase    :  np.ndarray ,					__lowercase    :  Union[float, List[float]] ,					__lowercase    :  Union[float, List[float]] ,					__lowercase    :  Optional[Union[str, ChannelDimension]] = None ,					**__lowercase    :  int ,					):






						'''simple docstring'''







						return normalize(__lowercase ,					mean=__lowercase ,					std=__lowercase ,					data_format=__lowercase ,					**__lowercase		)





					def        SCREAMING_SNAKE_CASE							(						self    :  str ,					__lowercase    :  ImageInput ,					__lowercase    :  Optional[bool] = None ,					__lowercase    :  Dict[str, int] = None ,					__lowercase    :  PILImageResampling = None ,					__lowercase    :  bool = None ,					__lowercase    :  int = None ,					__lowercase    :  Optional[bool] = None ,					__lowercase    :  Optional[float] = None ,					__lowercase    :  Optional[bool] = None ,					__lowercase    :  Optional[Union[float, List[float]]] = None ,					__lowercase    :  Optional[Union[float, List[float]]] = None ,					__lowercase    :  Optional[Union[str, TensorType]] = None ,					__lowercase    :  Union[str, ChannelDimension] = ChannelDimension.FIRST ,					**__lowercase    :  Tuple ,					):






						'''simple docstring'''







						UpperCAmelCase_								=     do_resize if do_resize is not None else self.do_resize
						UpperCAmelCase_								=     do_rescale if do_rescale is not None else self.do_rescale
						UpperCAmelCase_								=     do_normalize if do_normalize is not None else self.do_normalize
						UpperCAmelCase_								=     do_center_crop if do_center_crop is not None else self.do_center_crop
						UpperCAmelCase_								=     crop_size if crop_size is not None else self.crop_size
						UpperCAmelCase_								=     get_size_dict(__lowercase ,					param_name="""crop_size""" ,					default_to_square=__lowercase		)
						UpperCAmelCase_								=     resample if resample is not None else self.resample
						UpperCAmelCase_								=     rescale_factor if rescale_factor is not None else self.rescale_factor
						UpperCAmelCase_								=     image_mean if image_mean is not None else self.image_mean
						UpperCAmelCase_								=     image_std if image_std is not None else self.image_std

						UpperCAmelCase_								=     size if size is not None else self.size
						UpperCAmelCase_								=     get_size_dict(__lowercase		)

						if not is_batched(__lowercase		):
							UpperCAmelCase_								=     [images]

						if not valid_images(__lowercase		):
							raise ValueError(
							    """Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, """
							    """torch.Tensor, tf.Tensor or jax.ndarray."""		)

						if do_resize and size is None:
							raise ValueError("""Size must be specified if do_resize is True."""		)

						if do_center_crop and crop_size is None:
							raise ValueError("""Crop size must be specified if do_center_crop is True."""		)

						if do_rescale and rescale_factor is None:
							raise ValueError("""Rescale factor must be specified if do_rescale is True."""		)

						# All transformations expect numpy arrays.
						UpperCAmelCase_								=     [to_numpy_array(__lowercase		) for image in images]

						if do_resize:
							UpperCAmelCase_								=     [self.resize(image=__lowercase ,					size=__lowercase ,					resample=__lowercase		) for image in images]

						if do_center_crop:
							UpperCAmelCase_								=     [self.center_crop(image=__lowercase ,					size=__lowercase		) for image in images]

						if do_rescale:
							UpperCAmelCase_								=     [self.rescale(image=__lowercase ,					scale=__lowercase		) for image in images]

						if do_normalize:
							UpperCAmelCase_								=     [self.normalize(image=__lowercase ,					mean=__lowercase ,					std=__lowercase		) for image in images]

						UpperCAmelCase_								=     [to_channel_dimension_format(__lowercase ,					__lowercase		) for image in images]

						UpperCAmelCase_								=     {"""pixel_values""": images}
						return BatchFeature(data=__lowercase ,					tensor_type=__lowercase		)









from math import factorial

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




def    A_(			A   ):
	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 = 60				,      A = 1000000   ):

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

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

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

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

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


