
import tensorflow as tf

from ...tf_utils import shape_list

class 							_UpperCamelCase					(       tf.keras.layers.Layer	):






			'''simple docstring'''

			def __init__(							self			:							Union[str, Any]    ,						snake_case_			:							Optional[Any]    ,						snake_case_			:							List[Any]    ,						snake_case_			:							Optional[int]    ,						snake_case_			:							Optional[int]    ,						snake_case_			:							str=1    ,						snake_case_			:							Dict=False    ,						**snake_case_			:							Tuple   ):
							super().__init__(**snake_case_   )

							UpperCamelCase_:				List[str]						=    vocab_size
							UpperCamelCase_:				Dict						=    d_embed
							UpperCamelCase_:				Optional[Any]						=    d_proj

							UpperCamelCase_:				Tuple						=    cutoffs + [vocab_size]
							UpperCamelCase_:				Dict						=    [0] + self.cutoffs
							UpperCamelCase_:				List[Any]						=    div_val

							UpperCamelCase_:				int						=    self.cutoffs[0]
							UpperCamelCase_:				Any						=    len(self.cutoffs   ) - 1
							UpperCamelCase_:				Dict						=    self.shortlist_size + self.n_clusters
							UpperCamelCase_:				Dict						=    keep_order

							UpperCamelCase_:				Tuple						=    []
							UpperCamelCase_:				Optional[Any]						=    []

			def    lowerCAmelCase__						(							self			:							List[Any]    ,						snake_case_			:							Union[str, Any]   ):
							if self.n_clusters > 0:
											UpperCamelCase_:				Optional[int]						=    self.add_weight(
											    shape=(self.n_clusters, self.d_embed)    ,						initializer="""zeros"""    ,						trainable=snake_case_    ,						name="""cluster_weight"""   )
											UpperCamelCase_:				str						=    self.add_weight(
											    shape=(self.n_clusters,)    ,						initializer="""zeros"""    ,						trainable=snake_case_    ,						name="""cluster_bias"""   )

							if self.div_val == 1:
											for i in range(len(self.cutoffs   )   ):
															if self.d_proj != self.d_embed:
																			UpperCamelCase_:				Tuple						=    self.add_weight(
																			    shape=(self.d_embed, self.d_proj)    ,						initializer="""zeros"""    ,						trainable=snake_case_    ,						name=f'''out_projs_._{i}'''    ,						)
																			self.out_projs.append(snake_case_   )
															else:
																			self.out_projs.append(snake_case_   )
															UpperCamelCase_:				List[Any]						=    self.add_weight(
															    shape=(self.vocab_size, self.d_embed)    ,						initializer="""zeros"""    ,						trainable=snake_case_    ,						name=f'''out_layers_._{i}_._weight'''    ,						)
															UpperCamelCase_:				Any						=    self.add_weight(
															    shape=(self.vocab_size,)    ,						initializer="""zeros"""    ,						trainable=snake_case_    ,						name=f'''out_layers_._{i}_._bias'''    ,						)
															self.out_layers.append((weight, bias)   )
							else:
											for i in range(len(self.cutoffs   )   ):
															UpperCamelCase_, UpperCamelCase_:				Optional[int]						=    self.cutoff_ends[i], self.cutoff_ends[i + 1]
															UpperCamelCase_:				int						=    self.d_embed // (self.div_val**i)

															UpperCamelCase_:				Union[str, Any]						=    self.add_weight(
															    shape=(d_emb_i, self.d_proj)    ,						initializer="""zeros"""    ,						trainable=snake_case_    ,						name=f'''out_projs_._{i}'''   )
															self.out_projs.append(snake_case_   )
															UpperCamelCase_:				Optional[int]						=    self.add_weight(
															    shape=(r_idx - l_idx, d_emb_i)    ,						initializer="""zeros"""    ,						trainable=snake_case_    ,						name=f'''out_layers_._{i}_._weight'''    ,						)
															UpperCamelCase_:				int						=    self.add_weight(
															    shape=(r_idx - l_idx,)    ,						initializer="""zeros"""    ,						trainable=snake_case_    ,						name=f'''out_layers_._{i}_._bias'''    ,						)
															self.out_layers.append((weight, bias)   )
							super().build(snake_case_   )

			@staticmethod
			def    lowerCAmelCase__						(							snake_case_			:							Tuple    ,						snake_case_			:							Any    ,						snake_case_			:							List[str]    ,						snake_case_			:							List[str]=None   ):
							UpperCamelCase_:				Dict						=    x
							if proj is not None:
											UpperCamelCase_:				Optional[int]						=    tf.einsum("""ibd,ed->ibe"""    ,						snake_case_    ,						snake_case_   )
							return tf.einsum("""ibd,nd->ibn"""    ,						snake_case_    ,						snake_case_   ) + b

			@staticmethod
			def    lowerCAmelCase__						(							snake_case_			:							List[Any]    ,						snake_case_			:							int   ):
							UpperCamelCase_:				List[str]						=    shape_list(snake_case_   )
							UpperCamelCase_:				List[Any]						=    tf.range(lp_size[0]    ,						dtype=target.dtype   )
							UpperCamelCase_:				str						=    tf.stack([r, target]    ,						1   )
							return tf.gather_nd(snake_case_    ,						snake_case_   )




			def    lowerCAmelCase__						(							self			:							Optional[int]    ,						snake_case_			:							Tuple    ,						snake_case_			:							Optional[int]    ,						snake_case_			:							Dict=True    ,						snake_case_			:							Tuple=False   ):
							UpperCamelCase_:				Any						=    0
							if self.n_clusters == 0:
											UpperCamelCase_:				Any						=    self._logit(snake_case_    ,						self.out_layers[0][0]    ,						self.out_layers[0][1]    ,						self.out_projs[0]   )
											if target is not None:
															UpperCamelCase_:				Tuple						=    tf.nn.sparse_softmax_cross_entropy_with_logits(labels=snake_case_    ,						logits=snake_case_   )
											UpperCamelCase_:				str						=    tf.nn.log_softmax(snake_case_    ,						axis=-1   )
							else:
											UpperCamelCase_:				int						=    shape_list(snake_case_   )
											UpperCamelCase_:				Optional[int]						=    []
											UpperCamelCase_:				Optional[Any]						=    tf.zeros(hidden_sizes[:2]   )
											for i in range(len(self.cutoffs   )   ):
															UpperCamelCase_, UpperCamelCase_:				int						=    self.cutoff_ends[i], self.cutoff_ends[i + 1]
															if target is not None:
																			UpperCamelCase_:				Optional[int]						=    (target >= l_idx) & (target < r_idx)
																			UpperCamelCase_:				List[Any]						=    tf.where(snake_case_   )
																			UpperCamelCase_:				Union[str, Any]						=    tf.boolean_mask(snake_case_    ,						snake_case_   ) - l_idx

															if self.div_val == 1:
																			UpperCamelCase_:				List[Any]						=    self.out_layers[0][0][l_idx:r_idx]
																			UpperCamelCase_:				str						=    self.out_layers[0][1][l_idx:r_idx]
															else:
																			UpperCamelCase_:				Union[str, Any]						=    self.out_layers[i][0]
																			UpperCamelCase_:				Union[str, Any]						=    self.out_layers[i][1]

															if i == 0:
																			UpperCamelCase_:				int						=    tf.concat([cur_W, self.cluster_weight]    ,						0   )
																			UpperCamelCase_:				List[str]						=    tf.concat([cur_b, self.cluster_bias]    ,						0   )

																			UpperCamelCase_:				int						=    self._logit(snake_case_    ,						snake_case_    ,						snake_case_    ,						self.out_projs[0]   )
																			UpperCamelCase_:				Dict						=    tf.nn.log_softmax(snake_case_   )
																			out.append(head_logprob[..., : self.cutoffs[0]]   )
																			if target is not None:
																							UpperCamelCase_:				Tuple						=    tf.boolean_mask(snake_case_    ,						snake_case_   )
																							UpperCamelCase_:				Optional[Any]						=    self._gather_logprob(snake_case_    ,						snake_case_   )
															else:
																			UpperCamelCase_:				Any						=    self._logit(snake_case_    ,						snake_case_    ,						snake_case_    ,						self.out_projs[i]   )
																			UpperCamelCase_:				List[str]						=    tf.nn.log_softmax(snake_case_   )
																			UpperCamelCase_:				int						=    self.cutoffs[0] + i - 1  # No probability for the head cluster
																			UpperCamelCase_:				List[Any]						=    head_logprob[..., cluster_prob_idx, None] + tail_logprob
																			out.append(snake_case_   )
																			if target is not None:
																							UpperCamelCase_:				Optional[Any]						=    tf.boolean_mask(snake_case_    ,						snake_case_   )
																							UpperCamelCase_:				Dict						=    tf.boolean_mask(snake_case_    ,						snake_case_   )
																							UpperCamelCase_:				Tuple						=    self._gather_logprob(snake_case_    ,						snake_case_   )
																							cur_logprob += cur_head_logprob[:, self.cutoff_ends[1] + i - 1]
															if target is not None:
																			loss += tf.scatter_nd(snake_case_    ,						-cur_logprob    ,						shape_list(snake_case_   )   )
											UpperCamelCase_:				Union[str, Any]						=    tf.concat(snake_case_    ,						axis=-1   )

							if target is not None:
											if return_mean:
															UpperCamelCase_:				Optional[Any]						=    tf.reduce_mean(snake_case_   )
											# Add the training-time loss value to the layer using `self.add_loss()`.
											self.add_loss(snake_case_   )

											# Log the loss as a metric (we could log arbitrary metrics,
											# including different metrics for training and inference.
											self.add_metric(snake_case_    ,						name=self.name    ,						aggregation="""mean""" if return_mean else """"""   )

							return out








def 							A__       (    lowerCamelCase = 4_00_00_00    )	->						int:
				UpperCamelCase_:				Dict						=    []
				UpperCamelCase_, UpperCamelCase_:				Optional[int]						=    0, 1
				while b <= n:
								if b % 2 == 0:
												even_fibs.append(lowerCamelCase    )
								UpperCamelCase_, UpperCamelCase_:				int						=    b, a + b
				return sum(lowerCamelCase    )


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






