
"""simple docstring"""

from dataclasses import dataclass
from typing import Optional

import numpy as np
import torch
import torch.nn as nn

from ..utils import BaseOutput, is_torch_version, randn_tensor
from .attention_processor import SpatialNorm
from .unet_ad_blocks import UNetMidBlockaD, get_down_block, get_up_block






@dataclass
class 	_lowercase       (    __UpperCAmelCase		):
	lowercase_				=     4_2






class 	_lowercase       (    nn.Module		):




	def __init__(			self		,			UpperCAmelCase_=3		,			UpperCAmelCase_=3		,			UpperCAmelCase_=("DownEncoderBlock2D",)		,			UpperCAmelCase_=(64,)		,			UpperCAmelCase_=2		,			UpperCAmelCase_=32		,			UpperCAmelCase_="silu"		,			UpperCAmelCase_=True		,			)		->							List[str]:
			super().__init__()
			lowerCamelCase					:      Union[str, Any]          =   layers_per_block

			lowerCamelCase					:      Any          =   torch.nn.Convad(
			    UpperCAmelCase_		,			block_out_channels[0]		,			kernel_size=3		,			stride=1		,			padding=1		,			)

			lowerCamelCase					:      int          =   None
			lowerCamelCase					:      Dict          =   nn.ModuleList([] )

			# down
			lowerCamelCase					:      List[Any]          =   block_out_channels[0]
			for i, down_block_type in enumerate(UpperCAmelCase_ ):
					lowerCamelCase					:      Union[str, Any]          =   output_channel
					lowerCamelCase					:      List[str]          =   block_out_channels[i]
					lowerCamelCase					:      Optional[int]          =   i == len(UpperCAmelCase_ ) - 1

					lowerCamelCase					:      int          =   get_down_block(
					    UpperCAmelCase_		,			num_layers=self.layers_per_block		,			in_channels=UpperCAmelCase_		,			out_channels=UpperCAmelCase_		,			add_downsample=not is_final_block		,			resnet_eps=1E-6		,			downsample_padding=0		,			resnet_act_fn=UpperCAmelCase_		,			resnet_groups=UpperCAmelCase_		,			attention_head_dim=UpperCAmelCase_		,			temb_channels=UpperCAmelCase_		,			)
					self.down_blocks.append(UpperCAmelCase_ )

			# mid
			lowerCamelCase					:      Tuple          =   UNetMidBlockaD(
			    in_channels=block_out_channels[-1]		,			resnet_eps=1E-6		,			resnet_act_fn=UpperCAmelCase_		,			output_scale_factor=1		,			resnet_time_scale_shift='default'		,			attention_head_dim=block_out_channels[-1]		,			resnet_groups=UpperCAmelCase_		,			temb_channels=UpperCAmelCase_		,			)

			# out
			lowerCamelCase					:      str          =   nn.GroupNorm(num_channels=block_out_channels[-1]		,			num_groups=UpperCAmelCase_		,			eps=1E-6 )
			lowerCamelCase					:      List[Any]          =   nn.SiLU()

			lowerCamelCase					:      Optional[int]          =   2 * out_channels if double_z else out_channels
			lowerCamelCase					:      Any          =   nn.Convad(block_out_channels[-1]		,			UpperCAmelCase_		,			3		,			padding=1 )

			lowerCamelCase					:      Optional[Any]          =   False




	def       _UpperCamelCase   (			self		,			UpperCAmelCase_ )		->							str:
			lowerCamelCase					:      Tuple          =   x
			lowerCamelCase					:      Any          =   self.conv_in(UpperCAmelCase_ )

			if self.training and self.gradient_checkpointing:

					def create_custom_forward(UpperCAmelCase_ ):
							def custom_forward(*UpperCAmelCase_ ):
									return module(*UpperCAmelCase_ )

							return custom_forward

					# down
					if is_torch_version('>='		,			'1.11.0' ):
							for down_block in self.down_blocks:
									lowerCamelCase					:      List[str]          =   torch.utils.checkpoint.checkpoint(
									    create_custom_forward(UpperCAmelCase_ )		,			UpperCAmelCase_		,			use_reentrant=UpperCAmelCase_ )
							# middle
							lowerCamelCase					:      List[str]          =   torch.utils.checkpoint.checkpoint(
							    create_custom_forward(self.mid_block )		,			UpperCAmelCase_		,			use_reentrant=UpperCAmelCase_ )
					else:
							for down_block in self.down_blocks:
									lowerCamelCase					:      Union[str, Any]          =   torch.utils.checkpoint.checkpoint(create_custom_forward(UpperCAmelCase_ )		,			UpperCAmelCase_ )
							# middle
							lowerCamelCase					:      List[str]          =   torch.utils.checkpoint.checkpoint(create_custom_forward(self.mid_block )		,			UpperCAmelCase_ )

			else:
					# down
					for down_block in self.down_blocks:
							lowerCamelCase					:      List[Any]          =   down_block(UpperCAmelCase_ )

					# middle
					lowerCamelCase					:      str          =   self.mid_block(UpperCAmelCase_ )

			# post-process
			lowerCamelCase					:      Any          =   self.conv_norm_out(UpperCAmelCase_ )
			lowerCamelCase					:      str          =   self.conv_act(UpperCAmelCase_ )
			lowerCamelCase					:      Union[str, Any]          =   self.conv_out(UpperCAmelCase_ )

			return sample






class 	_lowercase       (    nn.Module		):




	def __init__(			self		,			UpperCAmelCase_=3		,			UpperCAmelCase_=3		,			UpperCAmelCase_=("UpDecoderBlock2D",)		,			UpperCAmelCase_=(64,)		,			UpperCAmelCase_=2		,			UpperCAmelCase_=32		,			UpperCAmelCase_="silu"		,			UpperCAmelCase_="group"		,			)		->							List[str]:
			super().__init__()
			lowerCamelCase					:      Union[str, Any]          =   layers_per_block

			lowerCamelCase					:      Dict          =   nn.Convad(
			    UpperCAmelCase_		,			block_out_channels[-1]		,			kernel_size=3		,			stride=1		,			padding=1		,			)

			lowerCamelCase					:      int          =   None
			lowerCamelCase					:      List[str]          =   nn.ModuleList([] )

			lowerCamelCase					:      Optional[Any]          =   in_channels if norm_type == 'spatial' else None

			# mid
			lowerCamelCase					:      Dict          =   UNetMidBlockaD(
			    in_channels=block_out_channels[-1]		,			resnet_eps=1E-6		,			resnet_act_fn=UpperCAmelCase_		,			output_scale_factor=1		,			resnet_time_scale_shift='default' if norm_type == 'group' else norm_type		,			attention_head_dim=block_out_channels[-1]		,			resnet_groups=UpperCAmelCase_		,			temb_channels=UpperCAmelCase_		,			)

			# up
			lowerCamelCase					:      Tuple          =   list(reversed(UpperCAmelCase_ ) )
			lowerCamelCase					:      List[Any]          =   reversed_block_out_channels[0]
			for i, up_block_type in enumerate(UpperCAmelCase_ ):
					lowerCamelCase					:      int          =   output_channel
					lowerCamelCase					:      Union[str, Any]          =   reversed_block_out_channels[i]

					lowerCamelCase					:      List[str]          =   i == len(UpperCAmelCase_ ) - 1

					lowerCamelCase					:      Optional[Any]          =   get_up_block(
					    UpperCAmelCase_		,			num_layers=self.layers_per_block + 1		,			in_channels=UpperCAmelCase_		,			out_channels=UpperCAmelCase_		,			prev_output_channel=UpperCAmelCase_		,			add_upsample=not is_final_block		,			resnet_eps=1E-6		,			resnet_act_fn=UpperCAmelCase_		,			resnet_groups=UpperCAmelCase_		,			attention_head_dim=UpperCAmelCase_		,			temb_channels=UpperCAmelCase_		,			resnet_time_scale_shift=UpperCAmelCase_		,			)
					self.up_blocks.append(UpperCAmelCase_ )
					lowerCamelCase					:      Dict          =   output_channel

			# out
			if norm_type == "spatial":
					lowerCamelCase					:      int          =   SpatialNorm(block_out_channels[0]		,			UpperCAmelCase_ )
			else:
					lowerCamelCase					:      List[str]          =   nn.GroupNorm(num_channels=block_out_channels[0]		,			num_groups=UpperCAmelCase_		,			eps=1E-6 )
			lowerCamelCase					:      Any          =   nn.SiLU()
			lowerCamelCase					:      List[str]          =   nn.Convad(block_out_channels[0]		,			UpperCAmelCase_		,			3		,			padding=1 )

			lowerCamelCase					:      Union[str, Any]          =   False




	def       _UpperCamelCase   (			self		,			UpperCAmelCase_		,			UpperCAmelCase_=None )		->							Optional[int]:
			lowerCamelCase					:      Union[str, Any]          =   z
			lowerCamelCase					:      str          =   self.conv_in(UpperCAmelCase_ )

			lowerCamelCase					:      Any          =   next(iter(self.up_blocks.parameters() ) ).dtype
			if self.training and self.gradient_checkpointing:

					def create_custom_forward(UpperCAmelCase_ ):
							def custom_forward(*UpperCAmelCase_ ):
									return module(*UpperCAmelCase_ )

							return custom_forward

					if is_torch_version('>='		,			'1.11.0' ):
							# middle
							lowerCamelCase					:      Dict          =   torch.utils.checkpoint.checkpoint(
							    create_custom_forward(self.mid_block )		,			UpperCAmelCase_		,			UpperCAmelCase_		,			use_reentrant=UpperCAmelCase_ )
							lowerCamelCase					:      Optional[Any]          =   sample.to(UpperCAmelCase_ )

							# up
							for up_block in self.up_blocks:
									lowerCamelCase					:      Tuple          =   torch.utils.checkpoint.checkpoint(
									    create_custom_forward(UpperCAmelCase_ )		,			UpperCAmelCase_		,			UpperCAmelCase_		,			use_reentrant=UpperCAmelCase_ )
					else:
							# middle
							lowerCamelCase					:      Union[str, Any]          =   torch.utils.checkpoint.checkpoint(
							    create_custom_forward(self.mid_block )		,			UpperCAmelCase_		,			UpperCAmelCase_ )
							lowerCamelCase					:      Optional[Any]          =   sample.to(UpperCAmelCase_ )

							# up
							for up_block in self.up_blocks:
									lowerCamelCase					:      Any          =   torch.utils.checkpoint.checkpoint(create_custom_forward(UpperCAmelCase_ )		,			UpperCAmelCase_		,			UpperCAmelCase_ )
			else:
					# middle
					lowerCamelCase					:      Any          =   self.mid_block(UpperCAmelCase_		,			UpperCAmelCase_ )
					lowerCamelCase					:      Union[str, Any]          =   sample.to(UpperCAmelCase_ )

					# up
					for up_block in self.up_blocks:
							lowerCamelCase					:      Tuple          =   up_block(UpperCAmelCase_		,			UpperCAmelCase_ )

        # post-process
			if latent_embeds is None:
					lowerCamelCase					:      int          =   self.conv_norm_out(UpperCAmelCase_ )
			else:
					lowerCamelCase					:      Optional[Any]          =   self.conv_norm_out(UpperCAmelCase_		,			UpperCAmelCase_ )
			lowerCamelCase					:      List[Any]          =   self.conv_act(UpperCAmelCase_ )
			lowerCamelCase					:      Any          =   self.conv_out(UpperCAmelCase_ )

			return sample






class 	_lowercase       (    nn.Module		):




	def __init__(			self		,			UpperCAmelCase_		,			UpperCAmelCase_		,			UpperCAmelCase_		,			UpperCAmelCase_=None		,			UpperCAmelCase_="random"		,			UpperCAmelCase_=False		,			UpperCAmelCase_=True )		->							Optional[int]:
			super().__init__()
			lowerCamelCase					:      List[Any]          =   n_e
			lowerCamelCase					:      Optional[Any]          =   vq_embed_dim
			lowerCamelCase					:      int          =   beta
			lowerCamelCase					:      str          =   legacy

			lowerCamelCase					:      Tuple          =   nn.Embedding(self.n_e		,			self.vq_embed_dim )
			self.embedding.weight.data.uniform_(-1.0 / self.n_e		,			1.0 / self.n_e )

			lowerCamelCase					:      List[str]          =   remap
			if self.remap is not None:
					self.register_buffer('used'		,			torch.tensor(np.load(self.remap ) ) )
					lowerCamelCase					:      List[Any]          =   self.used.shape[0]
					lowerCamelCase					:      Optional[Any]          =   unknown_index  # "random" or "extra" or integer
					if self.unknown_index == "extra":
							lowerCamelCase					:      int          =   self.re_embed
							lowerCamelCase					:      List[Any]          =   self.re_embed + 1
					print(
					    F"""Remapping {self.n_e} indices to {self.re_embed} indices. """
					    F"""Using {self.unknown_index} for unknown indices.""" )
			else:
					lowerCamelCase					:      List[Any]          =   n_e

			lowerCamelCase					:      Optional[Any]          =   sane_index_shape




	def       _UpperCamelCase   (			self		,			UpperCAmelCase_ )		->							List[Any]:
			lowerCamelCase					:      str          =   inds.shape
			assert len(UpperCAmelCase_ ) > 1
			lowerCamelCase					:      Dict          =   inds.reshape(ishape[0]		,			-1 )
			lowerCamelCase					:      List[Any]          =   self.used.to(UpperCAmelCase_ )
			lowerCamelCase					:      int          =   (inds[:, :, None] == used[None, None, ...]).long()
			lowerCamelCase					:      Tuple          =   match.argmax(-1 )
			lowerCamelCase					:      Dict          =   match.sum(2 ) < 1
			if self.unknown_index == "random":
					lowerCamelCase					:      List[str]          =   torch.randint(0		,			self.re_embed		,			size=new[unknown].shape ).to(device=new.device )
			else:
					lowerCamelCase					:      Tuple          =   self.unknown_index
			return new.reshape(UpperCAmelCase_ )




	def       _UpperCamelCase   (			self		,			UpperCAmelCase_ )		->							List[Any]:
			lowerCamelCase					:      Optional[int]          =   inds.shape
			assert len(UpperCAmelCase_ ) > 1
			lowerCamelCase					:      Union[str, Any]          =   inds.reshape(ishape[0]		,			-1 )
			lowerCamelCase					:      Union[str, Any]          =   self.used.to(UpperCAmelCase_ )
			if self.re_embed > self.used.shape[0]:  # extra token
					lowerCamelCase					:      Tuple          =   0  # simply set to zero
			lowerCamelCase					:      Dict          =   torch.gather(used[None, :][inds.shape[0] * [0], :]		,			1		,			UpperCAmelCase_ )
			return back.reshape(UpperCAmelCase_ )




	def       _UpperCamelCase   (			self		,			UpperCAmelCase_ )		->							List[str]:
			# reshape z -> (batch, height, width, channel) and flatten
			lowerCamelCase					:      Union[str, Any]          =   z.permute(0		,			2		,			3		,			1 ).contiguous()
			lowerCamelCase					:      Union[str, Any]          =   z.view(-1		,			self.vq_embed_dim )

			# distances from z to embeddings e_j (z - e)^2 = z^2 + e^2 - 2 e * z
			lowerCamelCase					:      Union[str, Any]          =   torch.argmin(torch.cdist(UpperCAmelCase_		,			self.embedding.weight )		,			dim=1 )

			lowerCamelCase					:      Any          =   self.embedding(UpperCAmelCase_ ).view(z.shape )
			lowerCamelCase					:      List[str]          =   None
			lowerCamelCase					:      int          =   None

			# compute loss for embedding
			if not self.legacy:
					lowerCamelCase					:      Optional[int]          =   self.beta * torch.mean((z_q.detach() - z) ** 2 ) + torch.mean((z_q - z.detach()) ** 2 )
			else:
					lowerCamelCase					:      str          =   torch.mean((z_q.detach() - z) ** 2 ) + self.beta * torch.mean((z_q - z.detach()) ** 2 )

			# preserve gradients
			lowerCamelCase					:      str          =   z + (z_q - z).detach()

			# reshape back to match original input shape
			lowerCamelCase					:      str          =   z_q.permute(0		,			3		,			1		,			2 ).contiguous()

			if self.remap is not None:
					lowerCamelCase					:      Tuple          =   min_encoding_indices.reshape(z.shape[0]		,			-1 )  # add batch axis
					lowerCamelCase					:      Optional[int]          =   self.remap_to_used(UpperCAmelCase_ )
					lowerCamelCase					:      int          =   min_encoding_indices.reshape(-1		,			1 )  # flatten

			if self.sane_index_shape:
					lowerCamelCase					:      int          =   min_encoding_indices.reshape(z_q.shape[0]		,			z_q.shape[2]		,			z_q.shape[3] )

			return z_q, loss, (perplexity, min_encodings, min_encoding_indices)




	def       _UpperCamelCase   (			self		,			UpperCAmelCase_		,			UpperCAmelCase_ )		->							int:
			# shape specifying (batch, height, width, channel)
			if self.remap is not None:
					lowerCamelCase					:      Optional[int]          =   indices.reshape(shape[0]		,			-1 )  # add batch axis
					lowerCamelCase					:      Dict          =   self.unmap_to_all(UpperCAmelCase_ )
					lowerCamelCase					:      Union[str, Any]          =   indices.reshape(-1 )  # flatten again

			# get quantized latent vectors
			lowerCamelCase					:      Union[str, Any]          =   self.embedding(UpperCAmelCase_ )

			if shape is not None:
					lowerCamelCase					:      List[str]          =   z_q.view(UpperCAmelCase_ )
					# reshape back to match original input shape
					lowerCamelCase					:      int          =   z_q.permute(0		,			3		,			1		,			2 ).contiguous()

			return z_q






class 	_lowercase       (    __UpperCAmelCase		):




	def __init__(			self		,			UpperCAmelCase_		,			UpperCAmelCase_=False )		->							List[Any]:
			lowerCamelCase					:      Tuple          =   parameters
			lowerCamelCase					:      Optional[int]          =   torch.chunk(UpperCAmelCase_		,			2		,			dim=1 )
			lowerCamelCase					:      str          =   torch.clamp(self.logvar		,			-30.0		,			20.0 )
			lowerCamelCase					:      int          =   deterministic
			lowerCamelCase					:      Union[str, Any]          =   torch.exp(0.5 * self.logvar )
			lowerCamelCase					:      Tuple          =   torch.exp(self.logvar )
			if self.deterministic:
					lowerCamelCase					:      Any          =   torch.zeros_like(
					    self.mean		,			device=self.parameters.device		,			dtype=self.parameters.dtype )




	def       _UpperCamelCase   (			self		,			UpperCAmelCase_ = None )		->							torch.FloatTensor:
			# make sure sample is on the same device as the parameters and has same dtype
			lowerCamelCase					:      str          =   randn_tensor(
			    self.mean.shape		,			generator=UpperCAmelCase_		,			device=self.parameters.device		,			dtype=self.parameters.dtype )
			lowerCamelCase					:      Optional[Any]          =   self.mean + self.std * sample
			return x




	def       _UpperCamelCase   (			self		,			UpperCAmelCase_=None )		->							Optional[int]:
			if self.deterministic:
					return torch.Tensor([0.0] )
			else:
					if other is None:
							return 0.5 * torch.sum(torch.pow(self.mean		,			2 ) + self.var - 1.0 - self.logvar		,			dim=[1, 2, 3] )
					else:
							return 0.5 * torch.sum(
							    torch.pow(self.mean - other.mean		,			2 ) / other.var
							    + self.var / other.var
							    - 1.0
							    - self.logvar
							    + other.logvar		,			dim=[1, 2, 3]		,			)




	def       _UpperCamelCase   (			self		,			UpperCAmelCase_		,			UpperCAmelCase_=[1, 2, 3] )		->							Union[str, Any]:
			if self.deterministic:
					return torch.Tensor([0.0] )
			lowerCamelCase					:      int          =   np.log(2.0 * np.pi )
			return 0.5 * torch.sum(logtwopi + self.logvar + torch.pow(sample - self.mean		,			2 ) / self.var		,			dim=UpperCAmelCase_ )




	def       _UpperCamelCase   (			self )		->							str:
			return self.mean








"""simple docstring"""

def 		UpperCAmelCase (		):





		'''simple docstring'''


		return 1
def 		UpperCAmelCase (		a_      ):





		'''simple docstring'''


		return 0 if x < 0 else two_pence(x - 2      ) + one_pence()
def 		UpperCAmelCase (		a_      ):





		'''simple docstring'''


		return 0 if x < 0 else five_pence(x - 5      ) + two_pence(a_      )
def 		UpperCAmelCase (		a_      ):





		'''simple docstring'''


		return 0 if x < 0 else ten_pence(x - 10      ) + five_pence(a_      )
def 		UpperCAmelCase (		a_      ):





		'''simple docstring'''


		return 0 if x < 0 else twenty_pence(x - 20      ) + ten_pence(a_      )
def 		UpperCAmelCase (		a_      ):





		'''simple docstring'''


		return 0 if x < 0 else fifty_pence(x - 50      ) + twenty_pence(a_      )
def 		UpperCAmelCase (		a_      ):





		'''simple docstring'''


		return 0 if x < 0 else one_pound(x - 100      ) + fifty_pence(a_      )
def 		UpperCAmelCase (		a_      ):





		'''simple docstring'''


		return 0 if x < 0 else two_pound(x - 200      ) + one_pound(a_      )
def 		UpperCAmelCase (		a_ = 200      ):





		'''simple docstring'''


		return two_pound(a_      )


if __name__ == "__main__":
					print(solution(int(input().strip())))






