
import io
import math
from typing import Dict, Optional, Union

import numpy as np
from huggingface_hub import hf_hub_download

from ...image_processing_utils import BaseImageProcessor, BatchFeature
from ...image_transforms import convert_to_rgb, normalize, to_channel_dimension_format, to_pil_image
from ...image_utils import (
    ChannelDimension,
    ImageInput,
    get_image_size,
    infer_channel_dimension_format,
    make_list_of_images,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, is_torch_available, is_vision_available, logging
from ...utils.import_utils import requires_backends


if is_vision_available():
     import textwrap

     from PIL import Image, ImageDraw, ImageFont

if is_torch_available():
     import torch

     from transformers.pytorch_utils import is_torch_greater_or_equal_than_1_11
else:
     __magic_name__            =  False


__magic_name__            =  logging.get_logger(__name__)
__magic_name__            =  '''ybelkada/fonts'''





def 	SCREAMING_SNAKE_CASE__    (      ):
    if is_torch_available() and not is_torch_greater_or_equal_than_1_11:
        raise ImportError(
            F"""You are using torch=={torch.__version__}, but torch>=1.11.0 is required to use """
            "Pix2StructImageProcessor. Please upgrade torch."							)





def 	SCREAMING_SNAKE_CASE__    (      __lowerCAmelCase    ,		__lowerCAmelCase    ,		__lowerCAmelCase							):
    requires_backends(__lowerCAmelCase    ,		["torch"]							)
    _check_torch_version()

    snake_case__						=				image_tensor.unsqueeze(0							)
    snake_case__						=				torch.nn.functional.unfold(__lowerCAmelCase    ,		(patch_height, patch_width)    ,		stride=(patch_height, patch_width)							)
    snake_case__						=				patches.reshape(image_tensor.size(0							)    ,		image_tensor.size(1							)    ,		__lowerCAmelCase    ,		__lowerCAmelCase    ,		-1							)
    snake_case__						=				patches.permute(0    ,		4    ,		2    ,		3    ,		1							).reshape(
        image_tensor.size(2							) // patch_height    ,		image_tensor.size(3							) // patch_width    ,		image_tensor.size(1							) * patch_height * patch_width    ,		)
    return patches.unsqueeze(0							)





def 	SCREAMING_SNAKE_CASE__    (      __lowerCAmelCase    ,		__lowerCAmelCase = 36    ,		__lowerCAmelCase = "black"    ,		__lowerCAmelCase = "white"    ,		__lowerCAmelCase = 5    ,		__lowerCAmelCase = 5    ,		__lowerCAmelCase = 5    ,		__lowerCAmelCase = 5    ,		__lowerCAmelCase = None    ,		__lowerCAmelCase = None    ,		):
    requires_backends(__lowerCAmelCase    ,		"vision"							)
    # Add new lines so that each line is no more than 80 characters.

    snake_case__						=				textwrap.TextWrapper(width=80							)
    snake_case__						=				wrapper.wrap(text=__lowerCAmelCase							)
    snake_case__						=				"\n".join(__lowerCAmelCase							)

    if font_bytes is not None and font_path is None:
        snake_case__						=				io.BytesIO(__lowerCAmelCase							)
    elif font_path is not None:
        snake_case__						=				font_path
    else:
        snake_case__						=				hf_hub_download(__lowerCAmelCase    ,		"Arial.TTF"							)
    snake_case__						=				ImageFont.truetype(__lowerCAmelCase    ,		encoding="UTF-8"    ,		size=__lowerCAmelCase							)

    # Use a temporary canvas to determine the width and height in pixels when
    # rendering the text.
    snake_case__						=				ImageDraw.Draw(Image.new("RGB"    ,		(1, 1)    ,		__lowerCAmelCase							)							)
    snake_case__						,					snake_case__						,					snake_case__						,					snake_case__						=				temp_draw.textbbox((0, 0)    ,		__lowerCAmelCase    ,		__lowerCAmelCase							)

    # Create the actual image with a bit of padding around the text.
    snake_case__						=				text_width + left_padding + right_padding
    snake_case__						=				text_height + top_padding + bottom_padding
    snake_case__						=				Image.new("RGB"    ,		(image_width, image_height)    ,		__lowerCAmelCase							)
    snake_case__						=				ImageDraw.Draw(__lowerCAmelCase							)
    draw.text(xy=(left_padding, top_padding)    ,		text=__lowerCAmelCase    ,		fill=__lowerCAmelCase    ,		font=__lowerCAmelCase							)
    return image





def 	SCREAMING_SNAKE_CASE__    (      __lowerCAmelCase    ,		__lowerCAmelCase    ,		**__lowerCAmelCase							):
    requires_backends(__lowerCAmelCase    ,		"vision"							)

    # Convert to PIL image if necessary
    snake_case__						=				to_pil_image(__lowerCAmelCase							)

    snake_case__						=				render_text(__lowerCAmelCase    ,		**__lowerCAmelCase							)
    snake_case__						=				max(header_image.width    ,		image.width							)

    snake_case__						=				int(image.height * (new_width / image.width)							)
    snake_case__						=				int(header_image.height * (new_width / header_image.width)							)

    snake_case__						=				Image.new("RGB"    ,		(new_width, new_height + new_header_height)    ,		"white"							)
    new_image.paste(header_image.resize((new_width, new_header_height)							)    ,		(0, 0)							)
    new_image.paste(image.resize((new_width, new_height)							)    ,		(0, new_header_height)							)

    # Convert back to the original framework if necessary
    snake_case__						=				to_numpy_array(__lowerCAmelCase							)

    if infer_channel_dimension_format(__lowerCAmelCase							) == ChannelDimension.LAST:
        snake_case__						=				to_channel_dimension_format(__lowerCAmelCase    ,		ChannelDimension.LAST							)

    return new_image





class 					_SCREAMING_SNAKE_CASE  (      __UpperCamelCase ):
      _A						:		Optional[Any]    	=     ['flattened_patches']
      def __init__(			self		,	lowerCamelCase = True		,	lowerCamelCase = True		,	lowerCamelCase = None		,	lowerCamelCase = 20_48		,	lowerCamelCase = False		,	**lowerCamelCase		,	):
          super().__init__(**lowerCamelCase )
          snake_case__						=				patch_size if patch_size is not None else {"height": 16, "width": 16}
          snake_case__						=				do_normalize
          snake_case__						=				do_convert_rgb
          snake_case__						=				max_patches
          snake_case__						=				is_vqa
      def A_			(			self		,	lowerCamelCase		,	lowerCamelCase		,	lowerCamelCase		,	**lowerCamelCase ):
          requires_backends(self.extract_flattened_patches		,	"torch" )
          _check_torch_version()

          # convert to torch
          snake_case__						=				to_channel_dimension_format(lowerCamelCase		,	ChannelDimension.FIRST )
          snake_case__						=				torch.from_numpy(lowerCamelCase )

          snake_case__						,					snake_case__						=				patch_size["height"], patch_size["width"]
          snake_case__						,					snake_case__						=				get_image_size(lowerCamelCase )

          # maximize scale s.t.
          snake_case__						=				math.sqrt(max_patches * (patch_height / image_height) * (patch_width / image_width) )
          snake_case__						=				max(min(math.floor(scale * image_height / patch_height )		,	lowerCamelCase )		,	1 )
          snake_case__						=				max(min(math.floor(scale * image_width / patch_width )		,	lowerCamelCase )		,	1 )
          snake_case__						=				max(num_feasible_rows * patch_height		,	1 )
          snake_case__						=				max(num_feasible_cols * patch_width		,	1 )

          snake_case__						=				torch.nn.functional.interpolate(
              image.unsqueeze(0 )		,	size=(resized_height, resized_width)		,	mode="bilinear"		,	align_corners=lowerCamelCase		,	antialias=lowerCamelCase		,	).squeeze(0 )

          # [1, rows, columns, patch_height * patch_width * image_channels]
          snake_case__						=				torch_extract_patches(lowerCamelCase		,	lowerCamelCase		,	lowerCamelCase )

          snake_case__						=				patches.shape
          snake_case__						=				patches_shape[1]
          snake_case__						=				patches_shape[2]
          snake_case__						=				patches_shape[3]

          # [rows * columns, patch_height * patch_width * image_channels]
          snake_case__						=				patches.reshape([rows * columns, depth] )

          # [rows * columns, 1]
          snake_case__						=				torch.arange(lowerCamelCase ).reshape([rows, 1] ).repeat(1		,	lowerCamelCase ).reshape([rows * columns, 1] )
          snake_case__						=				torch.arange(lowerCamelCase ).reshape([1, columns] ).repeat(lowerCamelCase		,	1 ).reshape([rows * columns, 1] )

          # Offset by 1 so the ids do not contain zeros, which represent padding.
          row_ids += 1
          col_ids += 1

          # Prepare additional patch features.
          # [rows * columns, 1]
          snake_case__						=				row_ids.to(torch.floataa )
          snake_case__						=				col_ids.to(torch.floataa )

          # [rows * columns, 2 + patch_height * patch_width * image_channels]
          snake_case__						=				torch.cat([row_ids, col_ids, patches]		,	-1 )

          # [max_patches, 2 + patch_height * patch_width * image_channels]
          snake_case__						=				torch.nn.functional.pad(lowerCamelCase		,	[0, 0, 0, max_patches - (rows * columns)] ).float()

          snake_case__						=				to_numpy_array(lowerCamelCase )

          return result
      def A_			(			self		,	lowerCamelCase		,	lowerCamelCase = None		,	**lowerCamelCase ):
          if image.dtype == np.uinta:
              snake_case__						=				image.astype(np.floataa )

          # take mean across the whole `image`
          snake_case__						=				np.mean(lowerCamelCase )
          snake_case__						=				np.std(lowerCamelCase )
          snake_case__						=				max(lowerCamelCase		,	1.0 / math.sqrt(np.prod(image.shape ) ) )

          return normalize(lowerCamelCase		,	mean=lowerCamelCase		,	std=lowerCamelCase		,	**lowerCamelCase )



      def A_			(			self		,	lowerCamelCase		,	lowerCamelCase = None		,	lowerCamelCase = None		,	lowerCamelCase = None		,	lowerCamelCase = None		,	lowerCamelCase = None		,	lowerCamelCase = None		,	lowerCamelCase = ChannelDimension.FIRST		,	**lowerCamelCase		,	):
          snake_case__						=				do_normalize if do_normalize is not None else self.do_normalize
          snake_case__						=				do_convert_rgb if do_convert_rgb is not None else self.do_convert_rgb
          snake_case__						=				patch_size if patch_size is not None else self.patch_size
          snake_case__						=				max_patches if max_patches is not None else self.max_patches
          snake_case__						=				self.is_vqa

          if kwargs.get("data_format"		,	lowerCamelCase ) is not None:
              raise ValueError("data_format is not an accepted input as the outputs are " )

          snake_case__						=				make_list_of_images(lowerCamelCase )

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

          # PIL RGBA images are converted to RGB
          if do_convert_rgb:
              snake_case__						=				[convert_to_rgb(lowerCamelCase ) for image in images]

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

          if is_vqa:
              if header_text is None:
                  raise ValueError("A header text must be provided for VQA models." )
              snake_case__						=				kwargs.pop("font_bytes"		,	lowerCamelCase )
              snake_case__						=				kwargs.pop("font_path"		,	lowerCamelCase )

              if isinstance(lowerCamelCase		,	lowerCamelCase ):
                  snake_case__						=				[header_text] * len(lowerCamelCase )

              snake_case__						=				[
                  render_header(lowerCamelCase		,	header_text[i]		,	font_bytes=lowerCamelCase		,	font_path=lowerCamelCase )
                  for i, image in enumerate(lowerCamelCase )
              ]

          if do_normalize:
              snake_case__						=				[self.normalize(image=lowerCamelCase ) for image in images]

          # convert to torch tensor and permute
          snake_case__						=				[
              self.extract_flattened_patches(image=lowerCamelCase		,	max_patches=lowerCamelCase		,	patch_size=lowerCamelCase )
              for image in images
          ]

          # create attention mask in numpy
          snake_case__						=				[(image.sum(axis=-1 ) != 0).astype(np.floataa ) for image in images]

          snake_case__						=				BatchFeature(
              data={"flattened_patches": images, "attention_mask": attention_masks}		,	tensor_type=lowerCamelCase )

          return encoded_outputs





from math import factorial





def 	SCREAMING_SNAKE_CASE__    (      __lowerCAmelCase = 100							):
    return sum(int(__lowerCAmelCase							) for x in str(factorial(__lowerCAmelCase							)							)							)


if __name__ == "__main__":
     print(solution(int(input('''Enter the Number: ''').strip())))



