



import torch
from torch import nn

class 	lowerCamelCase_    ( nn.Module						):






      '''simple docstring'''







      def __init__(	self      :			List[str]	,	__lowerCamelCase      :			Tuple	,	__lowerCamelCase      :			Optional[Any]	,	__lowerCamelCase      :			Tuple	,	__lowerCamelCase      :			List[Any]	,	__lowerCamelCase      :			Optional[int]=1	,	__lowerCamelCase      :			str=False )      ->				Optional[Any]:
         super().__init__()

         A							:					str              =						n_token
         A							:					Optional[Any]              =						d_embed
         A							:					str              =						d_proj

         A							:					Optional[Any]              =						cutoffs + [n_token]
         A							:					Dict              =						[0] + self.cutoffs
         A							:					Tuple              =						div_val

         A							:					int              =						self.cutoffs[0]
         A							:					str              =						len(self.cutoffs ) - 1
         A							:					List[Any]              =						self.shortlist_size + self.n_clusters

         if self.n_clusters > 0:
            A							:					str              =						nn.Parameter(torch.zeros(self.n_clusters	,	self.d_embed ) )
            A							:					str              =						nn.Parameter(torch.zeros(self.n_clusters ) )

         A							:					str              =						nn.ModuleList()
         A							:					str              =						nn.ParameterList()

         if div_val == 1:
            for i in range(len(self.cutoffs ) ):
               if d_proj != d_embed:
                  self.out_projs.append(nn.Parameter(torch.FloatTensor(__lowerCAmelCase	,	__lowerCAmelCase ) ) )
               else:
                  self.out_projs.append(__lowerCAmelCase )

            self.out_layers.append(nn.Linear(__lowerCAmelCase	,	__lowerCAmelCase ) )
         else:
            for i in range(len(self.cutoffs ) ):
               A       , A							:					Dict              =						self.cutoff_ends[i], self.cutoff_ends[i + 1]
               A							:					List[Any]              =						d_embed // (div_val**i)

               self.out_projs.append(nn.Parameter(torch.FloatTensor(__lowerCAmelCase	,	__lowerCAmelCase ) ) )

               self.out_layers.append(nn.Linear(__lowerCAmelCase	,	r_idx - l_idx ) )

         A							:					Any              =						keep_order







      def 			SCREAMING_SNAKE_CASE__		(	self      :			List[Any]	,	__lowerCamelCase      :			Union[str, Any]	,	__lowerCamelCase      :			Dict	,	__lowerCamelCase      :			str	,	__lowerCamelCase      :			Optional[int] )      ->				Dict:







         if proj is None:
            A							:					Dict              =						nn.functional.linear(__lowerCAmelCase	,	__lowerCAmelCase	,	bias=__lowerCAmelCase )
         else:
            # if CUDA_MAJOR <= 9 and CUDA_MINOR <= 1:
            A							:					int              =						nn.functional.linear(__lowerCAmelCase	,	proj.t().contiguous() )
            A							:					int              =						nn.functional.linear(__lowerCAmelCase	,	__lowerCAmelCase	,	bias=__lowerCAmelCase )
            # else:
            #     logit = torch.einsum('bd,de,ev->bv', (hidden, proj, weight.t()))
            #     if bias is not None:
            #         logit = logit + bias

         return logit







      def 			SCREAMING_SNAKE_CASE__		(	self      :			Optional[int]	,	__lowerCamelCase      :			Tuple	,	__lowerCamelCase      :			Dict=None	,	__lowerCamelCase      :			Any=False )      ->				Any:







         if labels is not None:
            # Shift so that tokens < n predict n
            A							:					int              =						hidden[..., :-1, :].contiguous()
            A							:					Tuple              =						labels[..., 1:].contiguous()
            A							:					int              =						hidden.view(-1	,	hidden.size(-1 ) )
            A							:					str              =						labels.view(-1 )
            if hidden.size(0 ) != labels.size(0 ):
               raise RuntimeError("Input and labels should have the same size in the batch dimension." )
         else:
            A							:					Tuple              =						hidden.view(-1	,	hidden.size(-1 ) )

         if self.n_clusters == 0:
            A							:					Optional[int]              =						self._compute_logit(__lowerCAmelCase	,	self.out_layers[0].weight	,	self.out_layers[0].bias	,	self.out_projs[0] )
            if labels is not None:
               A							:					str              =						labels != -1_00
               A							:					Union[str, Any]              =						torch.zeros_like(__lowerCAmelCase	,	dtype=hidden.dtype	,	device=hidden.device )
               A							:					List[Any]              =						(
                   -nn.functional.log_softmax(__lowerCAmelCase	,	dim=-1 )[mask].gather(1	,	labels[mask].unsqueeze(1 ) ).squeeze(1 )
               )
            else:
               A							:					Dict              =						nn.functional.log_softmax(__lowerCAmelCase	,	dim=-1 )
         else:
            # construct weights and biases
            A       , A							:					str              =						[], []
            for i in range(len(self.cutoffs ) ):
               if self.div_val == 1:
                  A       , A							:					Optional[Any]              =						self.cutoff_ends[i], self.cutoff_ends[i + 1]
                  A							:					Union[str, Any]              =						self.out_layers[0].weight[l_idx:r_idx]
                  A							:					Optional[int]              =						self.out_layers[0].bias[l_idx:r_idx]
               else:
                  A							:					List[str]              =						self.out_layers[i].weight
                  A							:					Union[str, Any]              =						self.out_layers[i].bias

               if i == 0:
                  A							:					str              =						torch.cat([weight_i, self.cluster_weight]	,	dim=0 )
                  A							:					Union[str, Any]              =						torch.cat([bias_i, self.cluster_bias]	,	dim=0 )

               weights.append(__lowerCAmelCase )
               biases.append(__lowerCAmelCase )

            A       , A       , A							:					Union[str, Any]              =						weights[0], biases[0], self.out_projs[0]

            A							:					str              =						self._compute_logit(__lowerCAmelCase	,	__lowerCAmelCase	,	__lowerCAmelCase	,	__lowerCAmelCase )
            A							:					Any              =						nn.functional.log_softmax(__lowerCAmelCase	,	dim=1 )

            if labels is None:
               A							:					Optional[int]              =						hidden.new_empty((head_logit.size(0 ), self.n_token) )
            else:
               A							:					List[str]              =						torch.zeros_like(__lowerCAmelCase	,	dtype=hidden.dtype	,	device=hidden.device )

            A							:					int              =						0
            A							:					int              =						[0] + self.cutoffs
            for i in range(len(__lowerCAmelCase ) - 1 ):
               A       , A							:					List[Any]              =						cutoff_values[i], cutoff_values[i + 1]

               if labels is not None:
                  A							:					Optional[Any]              =						(labels >= l_idx) & (labels < r_idx)
                  A							:					List[str]              =						mask_i.nonzero().squeeze()

                  if indices_i.numel() == 0:
                     continue

                  A							:					Union[str, Any]              =						labels.index_select(0	,	__lowerCAmelCase ) - l_idx
                  A							:					Union[str, Any]              =						head_logprob.index_select(0	,	__lowerCAmelCase )
                  A							:					List[Any]              =						hidden.index_select(0	,	__lowerCAmelCase )
               else:
                  A							:					List[Any]              =						hidden

               if i == 0:
                  if labels is not None:
                     A							:					Any              =						head_logprob_i.gather(1	,	target_i[:, None] ).squeeze(1 )
                  else:
                     A							:					int              =						head_logprob[:, : self.cutoffs[0]]
               else:
                  A       , A       , A							:					List[str]              =						weights[i], biases[i], self.out_projs[i]

                  A							:					Optional[Any]              =						self._compute_logit(__lowerCAmelCase	,	__lowerCAmelCase	,	__lowerCAmelCase	,	__lowerCAmelCase )
                  A							:					int              =						nn.functional.log_softmax(__lowerCAmelCase	,	dim=1 )
                  A							:					Dict              =						self.cutoffs[0] + i - 1  # No probability for the head cluster
                  if labels is not None:
                     A							:					Dict              =						head_logprob_i[:, cluster_prob_idx] + tail_logprob_i.gather(
                         1	,	target_i[:, None] ).squeeze(1 )
                  else:
                     A							:					Dict              =						head_logprob[:, cluster_prob_idx, None] + tail_logprob_i
                     A							:					Optional[Any]              =						logprob_i

               if labels is not None:
                  if (hasattr(self	,	"keep_order" ) and self.keep_order) or keep_order:
                     out.index_copy_(0	,	__lowerCAmelCase	,	-logprob_i )
                  else:
                     out[offset : offset + logprob_i.size(0 )].copy_(-logprob_i )
                  offset += logprob_i.size(0 )

         return out







      def 			SCREAMING_SNAKE_CASE__		(	self      :			List[Any]	,	__lowerCamelCase      :			Optional[Any] )      ->				List[str]:







         if self.n_clusters == 0:
            A							:					Optional[Any]              =						self._compute_logit(__lowerCAmelCase	,	self.out_layers[0].weight	,	self.out_layers[0].bias	,	self.out_projs[0] )
            return nn.functional.log_softmax(__lowerCAmelCase	,	dim=-1 )
         else:
            # construct weights and biases
            A       , A							:					Optional[int]              =						[], []
            for i in range(len(self.cutoffs ) ):
               if self.div_val == 1:
                  A       , A							:					List[Any]              =						self.cutoff_ends[i], self.cutoff_ends[i + 1]
                  A							:					Optional[int]              =						self.out_layers[0].weight[l_idx:r_idx]
                  A							:					Union[str, Any]              =						self.out_layers[0].bias[l_idx:r_idx]
               else:
                  A							:					List[str]              =						self.out_layers[i].weight
                  A							:					Optional[int]              =						self.out_layers[i].bias

               if i == 0:
                  A							:					Tuple              =						torch.cat([weight_i, self.cluster_weight]	,	dim=0 )
                  A							:					Optional[int]              =						torch.cat([bias_i, self.cluster_bias]	,	dim=0 )

               weights.append(__lowerCAmelCase )
               biases.append(__lowerCAmelCase )

            A       , A       , A							:					Optional[Any]              =						weights[0], biases[0], self.out_projs[0]
            A							:					Tuple              =						self._compute_logit(__lowerCAmelCase	,	__lowerCAmelCase	,	__lowerCAmelCase	,	__lowerCAmelCase )

            A							:					Optional[int]              =						hidden.new_empty((head_logit.size(0 ), self.n_token) )
            A							:					Tuple              =						nn.functional.log_softmax(__lowerCAmelCase	,	dim=1 )

            A							:					List[str]              =						[0] + self.cutoffs
            for i in range(len(__lowerCAmelCase ) - 1 ):
               A       , A							:					List[str]              =						cutoff_values[i], cutoff_values[i + 1]

               if i == 0:
                  A							:					int              =						head_logprob[:, : self.cutoffs[0]]
               else:
                  A       , A       , A							:					Tuple              =						weights[i], biases[i], self.out_projs[i]

                  A							:					List[str]              =						self._compute_logit(__lowerCAmelCase	,	__lowerCAmelCase	,	__lowerCAmelCase	,	__lowerCAmelCase )
                  A							:					List[str]              =						nn.functional.log_softmax(__lowerCAmelCase	,	dim=1 )

                  A							:					Any              =						head_logprob[:, -i] + tail_logprob_i
                  A							:					List[str]              =						logprob_i

            return out




from math import sqrt




def 	UpperCAmelCase   (						_lowerCamelCase = 100_0000    ):
			A							:					int              =						0
			A							:					int              =						0
			A							:					int

			while num_cuboids <= limit:
						max_cuboid_size += 1
						for sum_shortest_sides in range(2 ,    2 * max_cuboid_size + 1    ):
									if sqrt(sum_shortest_sides**2 + max_cuboid_size**2    ).is_integer():
												num_cuboids += (
												    min(_lowerCamelCase ,    sum_shortest_sides // 2    )
												    - max(1 ,    sum_shortest_sides - max_cuboid_size    )
												    + 1
												)

			return max_cuboid_size


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