
from typing import Optional, Tuple, Union

import flax
import flax.linen as nn
import jax
import jax.numpy as jnp
from flax.core.frozen_dict import FrozenDict

from ..configuration_utils import ConfigMixin, flax_register_to_config
from ..utils import BaseOutput
from .embeddings_flax import FlaxTimestepEmbedding, FlaxTimesteps
from .modeling_flax_utils import FlaxModelMixin
from .unet_ad_blocks_flax import (
    FlaxCrossAttnDownBlockaD,
    FlaxDownBlockaD,
    FlaxUNetMidBlockaDCrossAttn,
)







@flax.struct.dataclass
class  UpperCamelCase__		(    SCREAMING_SNAKE_CASE_   ):







	'''simple docstring'''
	_lowerCAmelCase							       =				42
	_lowerCAmelCase							       =				42







class  UpperCamelCase__		(    nn.Module   ):







	'''simple docstring'''
	_lowerCAmelCase							       =				42
	_lowerCAmelCase							       =				(16, 32, 96, 256)
	_lowerCAmelCase							       =				jnp.floataa





	def   __snake_case				(			self		):
					A__  :	Optional[Any]         =							nn.Conv(
					    self.block_out_channels[0]				,       kernel_size=(3, 3)				,       padding=((1, 1), (1, 1))				,       dtype=self.dtype				,       )

					A__  :	int         =							[]
					for i in range(len(self.block_out_channels		) - 1		):
									A__  :	Optional[Any]         =							self.block_out_channels[i]
									A__  :	str         =							self.block_out_channels[i + 1]
									A__  :	str         =							nn.Conv(
									    _lowerCAmelCase				,       kernel_size=(3, 3)				,       padding=((1, 1), (1, 1))				,       dtype=self.dtype				,       )
									blocks.append(_lowerCAmelCase		)
									A__  :	Optional[int]         =							nn.Conv(
									    _lowerCAmelCase				,       kernel_size=(3, 3)				,       strides=(2, 2)				,       padding=((1, 1), (1, 1))				,       dtype=self.dtype				,       )
									blocks.append(_lowerCAmelCase		)
					A__  :	str         =							blocks

					A__  :	Optional[Any]         =							nn.Conv(
					    self.conditioning_embedding_channels				,       kernel_size=(3, 3)				,       padding=((1, 1), (1, 1))				,       kernel_init=nn.initializers.zeros_init()				,       bias_init=nn.initializers.zeros_init()				,       dtype=self.dtype				,       )





	def __call__(			self				,       UpperCamelCase__		):
					A__  :	Optional[int]         =							self.conv_in(_lowerCAmelCase		)
					A__  :	Any         =							nn.silu(_lowerCAmelCase		)

					for block in self.blocks:
									A__  :	Any         =							block(_lowerCAmelCase		)
									A__  :	Dict         =							nn.silu(_lowerCAmelCase		)

					A__  :	Union[str, Any]         =							self.conv_out(_lowerCAmelCase		)

					return embedding







@flax_register_to_config
class  UpperCamelCase__		(    nn.Module,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_   ):







	'''simple docstring'''
	_lowerCAmelCase							       =				32
	_lowerCAmelCase							       =				4
	_lowerCAmelCase							       =				(
	    "CrossAttnDownBlock2D",
	    "CrossAttnDownBlock2D",
	    "CrossAttnDownBlock2D",
	    "DownBlock2D",
	)
	_lowerCAmelCase							       =				False
	_lowerCAmelCase							       =				(320, 640, 1_280, 1_280)
	_lowerCAmelCase							       =				2
	_lowerCAmelCase							       =				8
	_lowerCAmelCase							       =				None
	_lowerCAmelCase							       =				1_280
	_lowerCAmelCase							       =				0.0
	_lowerCAmelCase							       =				False
	_lowerCAmelCase							       =				jnp.floataa
	_lowerCAmelCase							       =				True
	_lowerCAmelCase							       =				0
	_lowerCAmelCase							       =				"rgb"
	_lowerCAmelCase							       =				(16, 32, 96, 256)





	def   __snake_case				(			self				,       UpperCamelCase__		):
					# init input tensors
					A__  :	Optional[int]         =							(1, self.in_channels, self.sample_size, self.sample_size)
					A__  :	Union[str, Any]         =							jnp.zeros(_lowerCAmelCase				,       dtype=jnp.floataa		)
					A__  :	Any         =							jnp.ones((1,)				,       dtype=jnp.intaa		)
					A__  :	Optional[Any]         =							jnp.zeros((1, 1, self.cross_attention_dim)				,       dtype=jnp.floataa		)
					A__  :	str         =							(1, 3, self.sample_size * 8, self.sample_size * 8)
					A__  :	Optional[int]         =							jnp.zeros(_lowerCAmelCase				,       dtype=jnp.floataa		)

					A__       ,							A__  :	Tuple         =							jax.random.split(_lowerCAmelCase		)
					A__  :	Optional[int]         =							{'''params''': params_rng, '''dropout''': dropout_rng}

					return self.init(_lowerCAmelCase				,       _lowerCAmelCase				,       _lowerCAmelCase				,       _lowerCAmelCase				,       _lowerCAmelCase		)["params"]





	def   __snake_case				(			self		):
					A__  :	Tuple         =							self.block_out_channels
					A__  :	List[Any]         =							block_out_channels[0] * 4

					# If `num_attention_heads` is not defined (which is the case for most models)
					# it will default to `attention_head_dim`. This looks weird upon first reading it and it is.
					# The reason for this behavior is to correct for incorrectly named variables that were introduced
					# when this library was created. The incorrect naming was only discovered much later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131
					# Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking
					# which is why we correct for the naming here.
					A__  :	Tuple         =							self.num_attention_heads or self.attention_head_dim

					# input
					A__  :	Dict         =							nn.Conv(
					    block_out_channels[0]				,       kernel_size=(3, 3)				,       strides=(1, 1)				,       padding=((1, 1), (1, 1))				,       dtype=self.dtype				,       )

					# time
					A__  :	int         =							FlaxTimesteps(
					    block_out_channels[0]				,       flip_sin_to_cos=self.flip_sin_to_cos				,       freq_shift=self.config.freq_shift		)
					A__  :	Union[str, Any]         =							FlaxTimestepEmbedding(_lowerCAmelCase				,       dtype=self.dtype		)

					A__  :	Optional[int]         =							FlaxControlNetConditioningEmbedding(
					    conditioning_embedding_channels=block_out_channels[0]				,       block_out_channels=self.conditioning_embedding_out_channels				,       )

					A__  :	Dict         =							self.only_cross_attention
					if isinstance(_lowerCAmelCase				,       _lowerCAmelCase		):
									A__  :	List[Any]         =							(only_cross_attention,) * len(self.down_block_types		)

					if isinstance(_lowerCAmelCase				,       _lowerCAmelCase		):
									A__  :	List[Any]         =							(num_attention_heads,) * len(self.down_block_types		)

					# down
					A__  :	List[Any]         =							[]
					A__  :	List[Any]         =							[]

					A__  :	List[Any]         =							block_out_channels[0]

					A__  :	str         =							nn.Conv(
					    _lowerCAmelCase				,       kernel_size=(1, 1)				,       padding='''VALID'''				,       kernel_init=nn.initializers.zeros_init()				,       bias_init=nn.initializers.zeros_init()				,       dtype=self.dtype				,       )
					controlnet_down_blocks.append(_lowerCAmelCase		)

					for i, down_block_type in enumerate(self.down_block_types		):
									A__  :	Tuple         =							output_channel
									A__  :	Any         =							block_out_channels[i]
									A__  :	int         =							i == len(_lowerCAmelCase		) - 1

									if down_block_type == "CrossAttnDownBlock2D":
													A__  :	Tuple         =							FlaxCrossAttnDownBlockaD(
													    in_channels=_lowerCAmelCase				,       out_channels=_lowerCAmelCase				,       dropout=self.dropout				,       num_layers=self.layers_per_block				,       num_attention_heads=num_attention_heads[i]				,       add_downsample=not is_final_block				,       use_linear_projection=self.use_linear_projection				,       only_cross_attention=only_cross_attention[i]				,       dtype=self.dtype				,       )
									else:
													A__  :	Any         =							FlaxDownBlockaD(
													    in_channels=_lowerCAmelCase				,       out_channels=_lowerCAmelCase				,       dropout=self.dropout				,       num_layers=self.layers_per_block				,       add_downsample=not is_final_block				,       dtype=self.dtype				,       )

									down_blocks.append(_lowerCAmelCase		)

									for _ in range(self.layers_per_block		):
													A__  :	Any         =							nn.Conv(
													    _lowerCAmelCase				,       kernel_size=(1, 1)				,       padding='''VALID'''				,       kernel_init=nn.initializers.zeros_init()				,       bias_init=nn.initializers.zeros_init()				,       dtype=self.dtype				,       )
													controlnet_down_blocks.append(_lowerCAmelCase		)

									if not is_final_block:
													A__  :	List[Any]         =							nn.Conv(
													    _lowerCAmelCase				,       kernel_size=(1, 1)				,       padding='''VALID'''				,       kernel_init=nn.initializers.zeros_init()				,       bias_init=nn.initializers.zeros_init()				,       dtype=self.dtype				,       )
													controlnet_down_blocks.append(_lowerCAmelCase		)

					A__  :	Tuple         =							down_blocks
					A__  :	Optional[int]         =							controlnet_down_blocks

					# mid
					A__  :	Union[str, Any]         =							block_out_channels[-1]
					A__  :	Optional[int]         =							FlaxUNetMidBlockaDCrossAttn(
					    in_channels=_lowerCAmelCase				,       dropout=self.dropout				,       num_attention_heads=num_attention_heads[-1]				,       use_linear_projection=self.use_linear_projection				,       dtype=self.dtype				,       )

					A__  :	int         =							nn.Conv(
					    _lowerCAmelCase				,       kernel_size=(1, 1)				,       padding='''VALID'''				,       kernel_init=nn.initializers.zeros_init()				,       bias_init=nn.initializers.zeros_init()				,       dtype=self.dtype				,       )





	def __call__(			self				,       UpperCamelCase__				,       UpperCamelCase__				,       UpperCamelCase__				,       UpperCamelCase__				,       UpperCamelCase__ = 1.0				,       UpperCamelCase__ = True				,       UpperCamelCase__ = False				,       ):
					A__  :	Any         =							self.controlnet_conditioning_channel_order
					if channel_order == "bgr":
									A__  :	int         =							jnp.flip(_lowerCAmelCase				,       axis=1		)

					# 1. time
					if not isinstance(_lowerCAmelCase				,       jnp.ndarray		):
									A__  :	List[str]         =							jnp.array([timesteps]				,       dtype=jnp.intaa		)
					elif isinstance(_lowerCAmelCase				,       jnp.ndarray		) and len(timesteps.shape		) == 0:
									A__  :	int         =							timesteps.astype(dtype=jnp.floataa		)
									A__  :	Tuple         =							jnp.expand_dims(_lowerCAmelCase				,       0		)

					A__  :	Dict         =							self.time_proj(_lowerCAmelCase		)
					A__  :	Tuple         =							self.time_embedding(_lowerCAmelCase		)

					# 2. pre-process
					A__  :	List[Any]         =							jnp.transpose(_lowerCAmelCase				,       (0, 2, 3, 1)		)
					A__  :	Union[str, Any]         =							self.conv_in(_lowerCAmelCase		)

					A__  :	int         =							jnp.transpose(_lowerCAmelCase				,       (0, 2, 3, 1)		)
					A__  :	Dict         =							self.controlnet_cond_embedding(_lowerCAmelCase		)
					sample += controlnet_cond

					# 3. down
					A__  :	Union[str, Any]         =							(sample,)
					for down_block in self.down_blocks:
									if isinstance(_lowerCAmelCase				,       _lowerCAmelCase		):
													A__       ,							A__  :	int         =							down_block(_lowerCAmelCase				,       _lowerCAmelCase				,       _lowerCAmelCase				,       deterministic=not train		)
									else:
													A__       ,							A__  :	Any         =							down_block(_lowerCAmelCase				,       _lowerCAmelCase				,       deterministic=not train		)
									down_block_res_samples += res_samples

					# 4. mid
					A__  :	List[str]         =							self.mid_block(_lowerCAmelCase				,       _lowerCAmelCase				,       _lowerCAmelCase				,       deterministic=not train		)

					# 5. contronet blocks
					A__  :	Any         =							()
					for down_block_res_sample, controlnet_block in zip(_lowerCAmelCase				,       self.controlnet_down_blocks		):
									A__  :	Union[str, Any]         =							controlnet_block(_lowerCAmelCase		)
									controlnet_down_block_res_samples += (down_block_res_sample,)

					A__  :	str         =							controlnet_down_block_res_samples

					A__  :	int         =							self.controlnet_mid_block(_lowerCAmelCase		)

					# 6. scaling
					A__  :	Optional[int]         =							[sample * conditioning_scale for sample in down_block_res_samples]
					mid_block_res_sample *= conditioning_scale

					if not return_dict:
									return (down_block_res_samples, mid_block_res_sample)

					return FlaxControlNetOutput(
					    down_block_res_samples=_lowerCAmelCase				,       mid_block_res_sample=_lowerCAmelCase		)

def 				SCREAMING_SNAKE_CASE     (      __UpperCamelCase :						int       ) ->       int:

				"""simple docstring"""







				if n == 1 or not isinstance(__UpperCamelCase							,						__UpperCamelCase       ):
								return 0
				elif n == 2:
								return 1
				else:
								A__  :	Any         =							[0, 1]
								for i in range(2							,						n + 1       ):
												sequence.append(sequence[i - 1] + sequence[i - 2]       )

								return sequence[n]

def 				SCREAMING_SNAKE_CASE     (      __UpperCamelCase :						int       ) ->       int:

				"""simple docstring"""







				A__  :	Dict         =							0
				A__  :	Optional[int]         =							2

				while digits < n:
								index += 1
								A__  :	Dict         =							len(str(fibonacci(__UpperCamelCase       )       )       )

				return index

def 				SCREAMING_SNAKE_CASE     (      __UpperCamelCase :						int = 10_00       ) ->       int:

				"""simple docstring"""







				return fibonacci_digits_index(__UpperCamelCase       )


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