

'''simple docstring'''
import os
import tempfile
import unittest

from transformers import NezhaConfig, is_torch_available
from transformers.models.auto import get_values
from transformers.testing_utils import require_torch, require_torch_gpu, slow, torch_device

from ...generation.test_utils import GenerationTesterMixin
from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
     import torch

     from transformers import (
         MODEL_FOR_PRETRAINING_MAPPING,
         NezhaForMaskedLM,
         NezhaForMultipleChoice,
         NezhaForNextSentencePrediction,
         NezhaForPreTraining,
         NezhaForQuestionAnswering,
         NezhaForSequenceClassification,
         NezhaForTokenClassification,
         NezhaModel,
     )
     from transformers.models.nezha.modeling_nezha import NEZHA_PRETRAINED_MODEL_ARCHIVE_LIST







class 							A__   :





  def __init__(		self				:     Optional[int]							, _a				:     str							, _a				:     Union[str, Any]=13							, _a				:     Tuple=7							, _a				:     List[str]=True							, _a				:     List[Any]=True							, _a				:     Dict=True							, _a				:     int=True							, _a				:     List[Any]=99							, _a				:     List[Any]=32							, _a				:     Optional[Any]=5							, _a				:     Optional[Any]=4							, _a				:     Tuple=37							, _a				:     int="gelu"							, _a				:     List[Any]=0.1							, _a				:     Optional[int]=0.1							, _a				:     Dict=128							, _a				:     str=32							, _a				:     List[Any]=16							, _a				:     Union[str, Any]=2							, _a				:     List[Any]=0.02							, _a				:     List[str]=3							, _a				:     List[Any]=4							, _a				:     int=None							, )     ->   Any:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =parent
       _SCREAMING_SNAKE_CASE							   =batch_size
       _SCREAMING_SNAKE_CASE							   =seq_length
       _SCREAMING_SNAKE_CASE							   =is_training
       _SCREAMING_SNAKE_CASE							   =use_input_mask
       _SCREAMING_SNAKE_CASE							   =use_token_type_ids
       _SCREAMING_SNAKE_CASE							   =use_labels
       _SCREAMING_SNAKE_CASE							   =vocab_size
       _SCREAMING_SNAKE_CASE							   =hidden_size
       _SCREAMING_SNAKE_CASE							   =num_hidden_layers
       _SCREAMING_SNAKE_CASE							   =num_attention_heads
       _SCREAMING_SNAKE_CASE							   =intermediate_size
       _SCREAMING_SNAKE_CASE							   =hidden_act
       _SCREAMING_SNAKE_CASE							   =hidden_dropout_prob
       _SCREAMING_SNAKE_CASE							   =attention_probs_dropout_prob
       _SCREAMING_SNAKE_CASE							   =max_position_embeddings
       _SCREAMING_SNAKE_CASE							   =type_vocab_size
       _SCREAMING_SNAKE_CASE							   =type_sequence_label_size
       _SCREAMING_SNAKE_CASE							   =initializer_range
       _SCREAMING_SNAKE_CASE							   =num_labels
       _SCREAMING_SNAKE_CASE							   =num_choices
       _SCREAMING_SNAKE_CASE							   =scope





  def 						A  (		self				:     str			)     ->   List[str]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =ids_tensor([self.batch_size, self.seq_length]							, self.vocab_size			)

       _SCREAMING_SNAKE_CASE							   =None
       if self.use_input_mask:
            _SCREAMING_SNAKE_CASE							   =random_attention_mask([self.batch_size, self.seq_length]			)

       _SCREAMING_SNAKE_CASE							   =None
       if self.use_token_type_ids:
            _SCREAMING_SNAKE_CASE							   =ids_tensor([self.batch_size, self.seq_length]							, self.type_vocab_size			)

       _SCREAMING_SNAKE_CASE							   =None
       _SCREAMING_SNAKE_CASE							   =None
       _SCREAMING_SNAKE_CASE							   =None
       if self.use_labels:
            _SCREAMING_SNAKE_CASE							   =ids_tensor([self.batch_size]							, self.type_sequence_label_size			)
            _SCREAMING_SNAKE_CASE							   =ids_tensor([self.batch_size, self.seq_length]							, self.num_labels			)
            _SCREAMING_SNAKE_CASE							   =ids_tensor([self.batch_size]							, self.num_choices			)

       _SCREAMING_SNAKE_CASE							   =self.get_config()

       return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels





  def 						A  (		self				:     int			)     ->   List[Any]:





       '''simple docstring'''






       return NezhaConfig(
           vocab_size=self.vocab_size							, hidden_size=self.hidden_size							, num_hidden_layers=self.num_hidden_layers							, num_attention_heads=self.num_attention_heads							, intermediate_size=self.intermediate_size							, hidden_act=self.hidden_act							, hidden_dropout_prob=self.hidden_dropout_prob							, attention_probs_dropout_prob=self.attention_probs_dropout_prob							, max_position_embeddings=self.max_position_embeddings							, type_vocab_size=self.type_vocab_size							, is_decoder=_a							, initializer_range=self.initializer_range							, )





  def 						A  (		self				:     Any			)     ->   Dict:





       '''simple docstring'''






       (
           (
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						
       )							   =self.prepare_config_and_inputs()

       _SCREAMING_SNAKE_CASE							   =True
       _SCREAMING_SNAKE_CASE							   =floats_tensor([self.batch_size, self.seq_length, self.hidden_size]			)
       _SCREAMING_SNAKE_CASE							   =ids_tensor([self.batch_size, self.seq_length]							, vocab_size=2			)

       return (
           config,
           input_ids,
           token_type_ids,
           input_mask,
           sequence_labels,
           token_labels,
           choice_labels,
           encoder_hidden_states,
           encoder_attention_mask,
       )





  def 						A  (		self				:     Union[str, Any]							, _a				:     List[str]							, _a				:     Optional[int]							, _a				:     List[str]							, _a				:     Optional[Any]							, _a				:     Tuple							, _a				:     str							, _a				:     Any			)     ->   Union[str, Any]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =NezhaModel(config=_a			)
       model.to(_a			)
       model.eval()
       _SCREAMING_SNAKE_CASE							   =model(_a							, attention_mask=_a							, token_type_ids=_a			)
       _SCREAMING_SNAKE_CASE							   =model(_a							, token_type_ids=_a			)
       _SCREAMING_SNAKE_CASE							   =model(_a			)
       self.parent.assertEqual(result.last_hidden_state.shape							, (self.batch_size, self.seq_length, self.hidden_size)			)
       self.parent.assertEqual(result.pooler_output.shape							, (self.batch_size, self.hidden_size)			)





  def 						A  (		self				:     Dict							, _a				:     List[Any]							, _a				:     Optional[Any]							, _a				:     Union[str, Any]							, _a				:     Dict							, _a				:     Tuple							, _a				:     int							, _a				:     int							, _a				:     Dict							, _a				:     int							, )     ->   Any:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =True
       _SCREAMING_SNAKE_CASE							   =NezhaModel(_a			)
       model.to(_a			)
       model.eval()
       _SCREAMING_SNAKE_CASE							   =model(
           _a							, attention_mask=_a							, token_type_ids=_a							, encoder_hidden_states=_a							, encoder_attention_mask=_a							, )
       _SCREAMING_SNAKE_CASE							   =model(
           _a							, attention_mask=_a							, token_type_ids=_a							, encoder_hidden_states=_a							, )
       _SCREAMING_SNAKE_CASE							   =model(_a							, attention_mask=_a							, token_type_ids=_a			)
       self.parent.assertEqual(result.last_hidden_state.shape							, (self.batch_size, self.seq_length, self.hidden_size)			)
       self.parent.assertEqual(result.pooler_output.shape							, (self.batch_size, self.hidden_size)			)





  def 						A  (		self				:     Any							, _a				:     List[Any]							, _a				:     Optional[int]							, _a				:     Tuple							, _a				:     int							, _a				:     Optional[Any]							, _a				:     Optional[Any]							, _a				:     List[Any]			)     ->   Dict:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =NezhaForMaskedLM(config=_a			)
       model.to(_a			)
       model.eval()
       _SCREAMING_SNAKE_CASE							   =model(_a							, attention_mask=_a							, token_type_ids=_a							, labels=_a			)
       self.parent.assertEqual(result.logits.shape							, (self.batch_size, self.seq_length, self.vocab_size)			)





  def 						A  (		self				:     Optional[Any]							, _a				:     List[str]							, _a				:     Optional[int]							, _a				:     int							, _a				:     str							, _a				:     List[str]							, _a				:     List[str]							, _a				:     Dict			)     ->   List[Any]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =NezhaForNextSentencePrediction(config=_a			)
       model.to(_a			)
       model.eval()
       _SCREAMING_SNAKE_CASE							   =model(
           _a							, attention_mask=_a							, token_type_ids=_a							, labels=_a							, )
       self.parent.assertEqual(result.logits.shape							, (self.batch_size, 2)			)





  def 						A  (		self				:     int							, _a				:     Dict							, _a				:     Optional[Any]							, _a				:     Optional[int]							, _a				:     Tuple							, _a				:     Dict							, _a				:     Any							, _a				:     Union[str, Any]			)     ->   List[str]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =NezhaForPreTraining(config=_a			)
       model.to(_a			)
       model.eval()
       _SCREAMING_SNAKE_CASE							   =model(
           _a							, attention_mask=_a							, token_type_ids=_a							, labels=_a							, next_sentence_label=_a							, )
       self.parent.assertEqual(result.prediction_logits.shape							, (self.batch_size, self.seq_length, self.vocab_size)			)
       self.parent.assertEqual(result.seq_relationship_logits.shape							, (self.batch_size, 2)			)





  def 						A  (		self				:     Union[str, Any]							, _a				:     str							, _a				:     Any							, _a				:     List[str]							, _a				:     List[str]							, _a				:     int							, _a				:     str							, _a				:     str			)     ->   Optional[int]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =NezhaForQuestionAnswering(config=_a			)
       model.to(_a			)
       model.eval()
       _SCREAMING_SNAKE_CASE							   =model(
           _a							, attention_mask=_a							, token_type_ids=_a							, start_positions=_a							, end_positions=_a							, )
       self.parent.assertEqual(result.start_logits.shape							, (self.batch_size, self.seq_length)			)
       self.parent.assertEqual(result.end_logits.shape							, (self.batch_size, self.seq_length)			)





  def 						A  (		self				:     Any							, _a				:     Any							, _a				:     Tuple							, _a				:     Tuple							, _a				:     Optional[int]							, _a				:     Dict							, _a				:     List[Any]							, _a				:     Union[str, Any]			)     ->   Optional[int]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.num_labels
       _SCREAMING_SNAKE_CASE							   =NezhaForSequenceClassification(_a			)
       model.to(_a			)
       model.eval()
       _SCREAMING_SNAKE_CASE							   =model(_a							, attention_mask=_a							, token_type_ids=_a							, labels=_a			)
       self.parent.assertEqual(result.logits.shape							, (self.batch_size, self.num_labels)			)





  def 						A  (		self				:     Optional[Any]							, _a				:     Dict							, _a				:     Optional[Any]							, _a				:     List[str]							, _a				:     Union[str, Any]							, _a				:     Optional[Any]							, _a				:     Dict							, _a				:     List[Any]			)     ->   Union[str, Any]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.num_labels
       _SCREAMING_SNAKE_CASE							   =NezhaForTokenClassification(config=_a			)
       model.to(_a			)
       model.eval()
       _SCREAMING_SNAKE_CASE							   =model(_a							, attention_mask=_a							, token_type_ids=_a							, labels=_a			)
       self.parent.assertEqual(result.logits.shape							, (self.batch_size, self.seq_length, self.num_labels)			)





  def 						A  (		self				:     Tuple							, _a				:     Union[str, Any]							, _a				:     Union[str, Any]							, _a				:     List[Any]							, _a				:     List[str]							, _a				:     str							, _a				:     Union[str, Any]							, _a				:     Dict			)     ->   Any:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.num_choices
       _SCREAMING_SNAKE_CASE							   =NezhaForMultipleChoice(config=_a			)
       model.to(_a			)
       model.eval()
       _SCREAMING_SNAKE_CASE							   =input_ids.unsqueeze(1			).expand(-1							, self.num_choices							, -1			).contiguous()
       _SCREAMING_SNAKE_CASE							   =token_type_ids.unsqueeze(1			).expand(-1							, self.num_choices							, -1			).contiguous()
       _SCREAMING_SNAKE_CASE							   =input_mask.unsqueeze(1			).expand(-1							, self.num_choices							, -1			).contiguous()
       _SCREAMING_SNAKE_CASE							   =model(
           _a							, attention_mask=_a							, token_type_ids=_a							, labels=_a							, )
       self.parent.assertEqual(result.logits.shape							, (self.batch_size, self.num_choices)			)





  def 						A  (		self				:     List[Any]			)     ->   Union[str, Any]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.prepare_config_and_inputs()
       (
           (
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						
       )							   =config_and_inputs
       _SCREAMING_SNAKE_CASE							   ={'input_ids': input_ids, 'token_type_ids': token_type_ids, 'attention_mask': input_mask}
       return config, inputs_dict







@require_torch
class 							A__   (	A__					,       A__					,       A__					,       unittest.TestCase  ):
  A__					=    (
      (
          NezhaModel,
          NezhaForMaskedLM,
          NezhaForMultipleChoice,
          NezhaForNextSentencePrediction,
          NezhaForPreTraining,
          NezhaForQuestionAnswering,
          NezhaForSequenceClassification,
          NezhaForTokenClassification,
      )
      if is_torch_available()
      else ()
  )
  A__					=    (
      {
          'feature-extraction': NezhaModel,
          'fill-mask': NezhaForMaskedLM,
          'question-answering': NezhaForQuestionAnswering,
          'text-classification': NezhaForSequenceClassification,
          'token-classification': NezhaForTokenClassification,
          'zero-shot': NezhaForSequenceClassification,
      }
      if is_torch_available()
      else {}
  )
  A__					=    True





  def 						A  (		self				:     int							, _a				:     Union[str, Any]							, _a				:     Union[str, Any]							, _a				:     Tuple=False			)     ->   int:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =super()._prepare_for_class(_a							, _a							, return_labels=_a			)

       if return_labels:
            if model_class in get_values(_a			):
                 _SCREAMING_SNAKE_CASE							   =torch.zeros(
                     (self.model_tester.batch_size, self.model_tester.seq_length)							, dtype=torch.long							, device=_a			)
                 _SCREAMING_SNAKE_CASE							   =torch.zeros(
                     self.model_tester.batch_size							, dtype=torch.long							, device=_a			)
       return inputs_dict





  def 						A  (		self				:     List[str]			)     ->   Tuple:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =NezhaModelTester(self			)
       _SCREAMING_SNAKE_CASE							   =ConfigTester(self							, config_class=_a							, hidden_size=37			)





  def 						A  (		self				:     str			)     ->   Any:





       '''simple docstring'''






       self.config_tester.run_common_tests()





  def 						A  (		self				:     List[Any]			)     ->   Optional[int]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs()
       self.model_tester.create_and_check_model(*_a			)





  def 						A  (		self				:     Dict			)     ->   List[str]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs_for_decoder()
       self.model_tester.create_and_check_model_as_decoder(*_a			)





  def 						A  (		self				:     Tuple			)     ->   List[Any]:





       '''simple docstring'''






       (
           (
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						(
           _SCREAMING_SNAKE_CASE
       )   ,						
       )							   =self.model_tester.prepare_config_and_inputs_for_decoder()

       _SCREAMING_SNAKE_CASE							   =None

       self.model_tester.create_and_check_model_as_decoder(
           _a							, _a							, _a							, _a							, _a							, _a							, _a							, _a							, _a							, )





  def 						A  (		self				:     List[str]			)     ->   int:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs()
       self.model_tester.create_and_check_for_masked_lm(*_a			)





  def 						A  (		self				:     int			)     ->   Optional[Any]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs()
       self.model_tester.create_and_check_for_multiple_choice(*_a			)





  def 						A  (		self				:     Optional[int]			)     ->   Dict:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs()
       self.model_tester.create_and_check_for_next_sequence_prediction(*_a			)





  def 						A  (		self				:     Optional[int]			)     ->   int:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs()
       self.model_tester.create_and_check_for_pretraining(*_a			)





  def 						A  (		self				:     Dict			)     ->   str:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs()
       self.model_tester.create_and_check_for_question_answering(*_a			)





  def 						A  (		self				:     Any			)     ->   Any:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs()
       self.model_tester.create_and_check_for_sequence_classification(*_a			)





  def 						A  (		self				:     Tuple			)     ->   Optional[int]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs()
       self.model_tester.create_and_check_for_token_classification(*_a			)





  @slow
  def 						A  (		self				:     str			)     ->   Union[str, Any]:





       '''simple docstring'''






       for model_name in NEZHA_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
            _SCREAMING_SNAKE_CASE							   =NezhaModel.from_pretrained(_a			)
            self.assertIsNotNone(_a			)





  @slow
  @require_torch_gpu
  def 						A  (		self				:     Optional[int]			)     ->   List[str]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE   ,						_SCREAMING_SNAKE_CASE							   =self.model_tester.prepare_config_and_inputs_for_common()
       for model_class in self.all_model_classes:
            # NezhaForMultipleChoice behaves incorrectly in JIT environments.
            if model_class == NezhaForMultipleChoice:
                 return

            _SCREAMING_SNAKE_CASE							   =True
            _SCREAMING_SNAKE_CASE							   =model_class(config=_a			)

            _SCREAMING_SNAKE_CASE							   =self._prepare_for_class(_a							, _a			)
            _SCREAMING_SNAKE_CASE							   =torch.jit.trace(
                _a							, (inputs_dict['input_ids'].to('cpu'			), inputs_dict['attention_mask'].to('cpu'			))			)

            with tempfile.TemporaryDirectory() as tmp:
                 torch.jit.save(_a							, os.path.join(_a							, 'bert.pt'			)			)
                 _SCREAMING_SNAKE_CASE							   =torch.jit.load(os.path.join(_a							, 'bert.pt'			)							, map_location=_a			)
                 loaded(inputs_dict['input_ids'].to(_a			)							, inputs_dict['attention_mask'].to(_a			)			)







@require_torch
class 							A__   (	unittest.TestCase  ):





  @slow
  def 						A  (		self				:     List[str]			)     ->   List[str]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =NezhaModel.from_pretrained('sijunhe/nezha-cn-base'			)
       _SCREAMING_SNAKE_CASE							   =torch.tensor([[0, 1, 2, 3, 4, 5]]			)
       _SCREAMING_SNAKE_CASE							   =torch.tensor([[0, 1, 1, 1, 1, 1]]			)
       with torch.no_grad():
            _SCREAMING_SNAKE_CASE							   =model(_a							, attention_mask=_a			)[0]
       _SCREAMING_SNAKE_CASE							   =torch.Size((1, 6, 768)			)
       self.assertEqual(output.shape							, _a			)
       _SCREAMING_SNAKE_CASE							   =torch.tensor([[[0.06_85, 0.24_41, 0.11_02], [0.06_00, 0.19_06, 0.13_49], [0.02_21, 0.08_19, 0.05_86]]]			)

       self.assertTrue(torch.allclose(output[:, 1:4, 1:4]							, _a							, atol=1e-4			)			)





  @slow
  def 						A  (		self				:     Union[str, Any]			)     ->   Dict:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							   =NezhaForMaskedLM.from_pretrained('sijunhe/nezha-cn-base'			)
       _SCREAMING_SNAKE_CASE							   =torch.tensor([[0, 1, 2, 3, 4, 5]]			)
       _SCREAMING_SNAKE_CASE							   =torch.tensor([[1, 1, 1, 1, 1, 1]]			)
       with torch.no_grad():
            _SCREAMING_SNAKE_CASE							   =model(_a							, attention_mask=_a			)[0]
       _SCREAMING_SNAKE_CASE							   =torch.Size((1, 6, 2_1128)			)
       self.assertEqual(output.shape							, _a			)
       _SCREAMING_SNAKE_CASE							   =torch.tensor(
           [[-2.79_39, -1.79_02, -2.21_89], [-2.85_85, -1.89_08, -2.37_23], [-2.64_99, -1.77_50, -2.25_58]]			)

       self.assertTrue(torch.allclose(output[:, 1:4, 1:4]							, _a							, atol=1e-4			)			)



'''simple docstring'''
def 	_lowerCAmelCase (						_UpperCamelCase						:					int = 50    )				->      int:
     """simple docstring"""




     _SCREAMING_SNAKE_CASE							   =[[0] * 3 for _ in range(length + 1    )]

     for row_length in range(length + 1    ):
          for tile_length in range(2							,			5    ):
               for tile_start in range(row_length - tile_length + 1    ):
                    different_colour_ways_number[row_length][tile_length - 2] += (
                        different_colour_ways_number[row_length - tile_start - tile_length][
                            tile_length - 2
                        ]
                        + 1
                    )

     return sum(different_colour_ways_number[length]    )


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