code: 
  
  
  
  import argparse
  import logging
  import os
  import sys
  import tempfile
  from pathlib import Path
  
  import lightning_base
  import pytest
  import pytorch_lightning as pl
  import torch
  from convert_pl_checkpoint_to_hf import convert_pl_to_hf
  from distillation import distill_main
  from finetune import SummarizationModule, main
  from huggingface_hub import list_models
  from parameterized import parameterized
  from run_eval import generate_summaries_or_translations
  from torch import nn
  
  from transformers import AutoConfig, AutoModelForSeqaSeqLM
  from transformers.testing_utils import CaptureStderr, CaptureStdout, TestCasePlus, require_torch_gpu, slow
  from utils import label_smoothed_nll_loss, lmap, load_json
  
  
  logging.basicConfig(level=logging.DEBUG)
  
  lowerCAmelCase__	:  List[str] 		=logging.getLogger()
  lowerCAmelCase__	:  List[Any] 		=torch.cuda.is_available()
  lowerCAmelCase__	:  List[str] 		={
      '''max_tokens_per_batch''': None,
      '''supervise_forward''': True,
      '''normalize_hidden''': True,
      '''label_smoothing''': 0.2,
      '''eval_max_gen_length''': None,
      '''eval_beams''': 1,
      '''val_metric''': '''loss''',
      '''save_top_k''': 1,
      '''adafactor''': True,
      '''early_stopping_patience''': 2,
      '''logger_name''': '''default''',
      '''length_penalty''': 0.5,
      '''cache_dir''': '''''',
      '''task''': '''summarization''',
      '''num_workers''': 2,
      '''alpha_hid''': 0,
      '''freeze_embeds''': True,
      '''enc_only''': False,
      '''tgt_suffix''': '''''',
      '''resume_from_checkpoint''': None,
      '''sortish_sampler''': True,
      '''student_decoder_layers''': 1,
      '''val_check_interval''': 1.0,
      '''output_dir''': '''''',
      '''fp16''': False,  # TODO(SS): set this to CUDA_AVAILABLE if ci installs apex or start using native amp
      '''no_teacher''': False,
      '''fp16_opt_level''': '''O1''',
      '''gpus''': 1 if CUDA_AVAILABLE else 0,
      '''n_tpu_cores''': 0,
      '''max_grad_norm''': 1.0,
      '''do_train''': True,
      '''do_predict''': True,
      '''accumulate_grad_batches''': 1,
      '''server_ip''': '''''',
      '''server_port''': '''''',
      '''seed''': 42,
      '''model_name_or_path''': '''sshleifer/bart-tiny-random''',
      '''config_name''': '''''',
      '''tokenizer_name''': '''facebook/bart-large''',
      '''do_lower_case''': False,
      '''learning_rate''': 0.3,
      '''lr_scheduler''': '''linear''',
      '''weight_decay''': 0.0,
      '''adam_epsilon''': 1E-08,
      '''warmup_steps''': 0,
      '''max_epochs''': 1,
      '''train_batch_size''': 2,
      '''eval_batch_size''': 2,
      '''max_source_length''': 12,
      '''max_target_length''': 12,
      '''val_max_target_length''': 12,
      '''test_max_target_length''': 12,
      '''fast_dev_run''': False,
      '''no_cache''': False,
      '''n_train''': -1,
      '''n_val''': -1,
      '''n_test''': -1,
      '''student_encoder_layers''': 1,
      '''freeze_encoder''': False,
      '''auto_scale_batch_size''': False,
      '''overwrite_output_dir''': False,
      '''student''': None,
  }
  
  
  
  
  
  
  def 			__lowercase     (				a__							,     a__     )       ->				Optional[Any]:
  							__SCREAMING_SNAKE_CASE								=      '\n'.join(a__     )
  							Path(a__     ).open('w'     ).writelines(a__     )
  
  
  lowerCAmelCase__	:  Tuple 		=[''' Sam ate lunch today.''', '''Sams lunch ingredients.''']
  lowerCAmelCase__	:  int 		=['''A very interesting story about what I ate for lunch.''', '''Avocado, celery, turkey, coffee''']
  lowerCAmelCase__	:  Optional[Any] 		='''patrickvonplaten/t5-tiny-random'''
  lowerCAmelCase__	:  Union[str, Any] 		='''sshleifer/t5-tinier-random'''
  lowerCAmelCase__	:  Optional[int] 		='''sshleifer/bart-tiny-random'''
  lowerCAmelCase__	:  List[Any] 		='''sshleifer/tiny-mbart'''
  lowerCAmelCase__	:  Union[str, Any] 		='''sshleifer/tiny-marian-en-de'''
  lowerCAmelCase__	:  Optional[Any] 		='''stas/tiny-wmt19-en-de'''
  
  
  lowerCAmelCase__	:  Optional[Any] 		=logging.StreamHandler(sys.stdout)
  logger.addHandler(stream_handler)
  logging.disable(logging.CRITICAL)  # remove noisy download output from tracebacks
  
  
  
  
  
  
  def 			__lowercase     (				a__     )       ->				List[Any]:
  							for split in ["train", "val", "test"]:
  														_dump_articles(os.path.join(a__							,     f"""{split}.source"""     )							,     a__     )
  														_dump_articles(os.path.join(a__							,     f"""{split}.target"""     )							,     a__     )
  							return tmp_dir
  
  class      UpperCAmelCase_						(     UpperCamelCase_ ):
  
  						'''simple docstring'''
  
  
  
  
  						@classmethod
  						def  _A			(					cls	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													logging.disable(logging.CRITICAL	)  # remove noisy download output from tracebacks
  													return cls
  
  
  
  
  
  
  						@slow
  						@require_torch_gpu
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      list_models()
  													__SCREAMING_SNAKE_CASE								=      'sshleifer'
  													__SCREAMING_SNAKE_CASE								=      [x.modelId for x in model_list if x.modelId.startswith(_A	)]
  													__SCREAMING_SNAKE_CASE								=      ['sshleifer/blenderbot-3B', 'sshleifer/blenderbot-90M']
  													__SCREAMING_SNAKE_CASE								=      []
  													for m in model_ids:
  																				if m in allowed_to_be_broken:
  																											continue
  																				try:
  																											AutoConfig.from_pretrained(_A	)
  																				except Exception:
  																											failures.append(_A	)
  													assert not failures, f"""The following models could not be loaded through AutoConfig: {failures}"""
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      {'student_encoder_layers': 2, 'student_decoder_layers': 1, 'no_teacher': True}
  													self._test_distiller_cli(_A	)
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      {
  													    'student_encoder_layers': 2,
  													    'student_decoder_layers': 1,
  													    'max_epochs': 4,
  													    'val_check_interval': 0.2_5,
  													    'alpha_hid': 2.0,
  													    'model_name_or_path': 'IGNORE_THIS_IT_DOESNT_GET_USED',
  													}
  													__SCREAMING_SNAKE_CASE								=      self._test_distiller_cli(_A   ,							check_contents=_A	)
  
  													__SCREAMING_SNAKE_CASE								=      list(Path(model.output_dir	).glob('*.ckpt'	)	)
  													self.assertEqual(1   ,							len(_A	)	)
  													__SCREAMING_SNAKE_CASE								=      list(Path(model.output_dir	).glob('**/*.bin'	)	)
  													self.assertEqual(len(_A	)   ,							2	)
  													__SCREAMING_SNAKE_CASE								=      lmap(str.strip   ,							Path(model.hparams.data_dir	).joinpath('test.source'	).open().readlines()	)
  													__SCREAMING_SNAKE_CASE								=      tempfile.mktemp()  # XXX: not being cleaned up
  													generate_summaries_or_translations(_A   ,							_A   ,							str(model.output_dir / 'best_tfmr'	)	)
  													self.assertTrue(Path(_A	).exists()	)
  
  													__SCREAMING_SNAKE_CASE								=      self.get_auto_remove_tmp_dir()
  													convert_pl_to_hf(ckpts[0]   ,							transformer_ckpts[0].parent   ,							_A	)
  													assert os.path.exists(os.path.join(_A   ,							'pytorch_model.bin'	)	)
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      AutoModelForSeqaSeqLM.from_pretrained(_A	)
  													__SCREAMING_SNAKE_CASE							, __SCREAMING_SNAKE_CASE								=      model.dummy_inputs['input_ids'], model.dummy_inputs['attention_mask']
  													__SCREAMING_SNAKE_CASE								=      torch.tensor([[0, 4, 8, 2], [0, 8, 2, 1]]   ,							dtype=torch.long   ,							device=model.device	)
  													__SCREAMING_SNAKE_CASE								=      target_ids[:, :-1].contiguous()  # Why this line?
  													__SCREAMING_SNAKE_CASE								=      target_ids[:, 1:].clone()  # why clone?
  													__SCREAMING_SNAKE_CASE								=      model(
  													    _A   ,							attention_mask=_A   ,							decoder_input_ids=_A   ,							labels=_A   ,							use_cache=_A	).loss
  
  													__SCREAMING_SNAKE_CASE								=      model(_A   ,							attention_mask=_A   ,							decoder_input_ids=_A   ,							use_cache=_A	).logits
  
  													__SCREAMING_SNAKE_CASE								=      nn.functional.log_softmax(_A   ,							dim=-1	)
  													__SCREAMING_SNAKE_CASE							, __SCREAMING_SNAKE_CASE								=      label_smoothed_nll_loss(
  													    _A   ,							_A   ,							0.1   ,							ignore_index=model.config.pad_token_id	)
  													with self.assertRaises(_A	):
  																				# TODO: understand why this breaks
  																				self.assertEqual(_A   ,							_A	)
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      {
  													    'student_encoder_layers': 2,
  													    'student_decoder_layers': 1,
  													    'num_train_epochs': 4,
  													    'val_check_interval': 0.2_5,
  													    'alpha_hid': 2.0,
  													    'task': 'translation',
  													    'model_name_or_path': 'IGNORE_THIS_IT_DOESNT_GET_USED',
  													    'tokenizer_name': MBART_TINY,
  													    'teacher': MBART_TINY,
  													    'src_lang': 'en_XX',
  													    'tgt_lang': 'ro_RO',
  													}
  													__SCREAMING_SNAKE_CASE								=      self._test_distiller_cli(_A   ,							check_contents=_A	)
  													assert model.model.config.model_type == "mbart"
  
  													__SCREAMING_SNAKE_CASE								=      list(Path(model.output_dir	).glob('*.ckpt'	)	)
  													self.assertEqual(1   ,							len(_A	)	)
  													__SCREAMING_SNAKE_CASE								=      list(Path(model.output_dir	).glob('**/*.bin'	)	)
  													__SCREAMING_SNAKE_CASE								=      list(Path(model.output_dir	).glob('best_tfmr/*'	)	)
  													assert len(_A	) > 2
  													self.assertEqual(len(_A	)   ,							2	)
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      {
  													    'student_encoder_layers': 1,
  													    'student_decoder_layers': 1,
  													    'alpha_hid': 2.0,
  													    'teacher': T5_TINY,
  													    'model_name_or_path': T5_TINY,
  													    'tokenizer_name': T5_TINY,
  													}
  													self._test_distiller_cli(_A	)
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      {
  													    'teacher': T5_TINY,
  													    'student': T5_TINIER,
  													    'model_name_or_path': T5_TINIER,
  													    'tokenizer_name': T5_TINIER,
  													}
  													self._test_distiller_cli(_A	)
  
  
  
  
  
  
  						def  _A			(					self   ,							_A   ,							_A=True	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      {
  													    'label_smoothing': 0.0,
  													    'early_stopping_patience': -1,
  													    'train_batch_size': 1,
  													    'eval_batch_size': 2,
  													    'max_epochs': 2,
  													    'alpha_mlm': 0.2,
  													    'alpha_ce': 0.8,
  													    'do_predict': True,
  													    'model_name_or_path': 'sshleifer/tinier_bart',
  													    'teacher': CHEAP_ARGS['model_name_or_path'],
  													    'val_check_interval': 0.5,
  													}
  													default_updates.update(_A	)
  													__SCREAMING_SNAKE_CASE								=      CHEAP_ARGS.copy()
  													__SCREAMING_SNAKE_CASE								=      make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()	)
  													__SCREAMING_SNAKE_CASE								=      self.get_auto_remove_tmp_dir()
  
  													args_d.update(data_dir=_A   ,							output_dir=_A   ,							**_A	)
  													__SCREAMING_SNAKE_CASE								=      distill_main(argparse.Namespace(**_A	)	)
  													if not check_contents:
  																				return model
  													__SCREAMING_SNAKE_CASE								=      os.listdir(_A	)
  													__SCREAMING_SNAKE_CASE								=      {os.path.basename(_A	) for p in contents}
  													__SCREAMING_SNAKE_CASE								=      [p for p in contents if p.endswith('ckpt'	)]
  													assert len(_A	) > 0
  
  													self.assertIn('test_generations.txt'   ,							_A	)
  													self.assertIn('test_results.txt'   ,							_A	)
  
  													__SCREAMING_SNAKE_CASE								=      load_json(model.metrics_save_path	)
  													__SCREAMING_SNAKE_CASE								=      metrics['val'][-1]
  													self.assertGreaterEqual(last_step_stats['val_avg_gen_time']   ,							0.0_1	)
  													self.assertGreaterEqual(1.0   ,							last_step_stats['val_avg_gen_time']	)
  													self.assertIsInstance(last_step_stats[f"""val_avg_{model.val_metric}"""]   ,							_A	)
  													__SCREAMING_SNAKE_CASE								=      int(args_d['max_epochs'] * (1 / args_d['val_check_interval']) + 1	)
  													self.assertEqual(len(metrics['val']	)   ,							_A	)
  													self.assertEqual(len(metrics['test']	)   ,							1	)
  													return model
  
  
  
  
  
  
  
  class      UpperCAmelCase_						(     UpperCamelCase_ ):
  
  						'''simple docstring'''
  
  
  
  
  						@parameterized.expand(
  						    [T5_TINY, BART_TINY, MBART_TINY, MARIAN_TINY, FSMT_TINY]   ,							)
  						def  _A			(					self   ,							_A	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      CHEAP_ARGS.copy()
  													__SCREAMING_SNAKE_CASE								=      'translation' if model in [MBART_TINY, MARIAN_TINY, FSMT_TINY] else 'summarization'
  													__SCREAMING_SNAKE_CASE								=      0.1 if task == 'translation' else 0
  
  													__SCREAMING_SNAKE_CASE								=      make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()	)
  													__SCREAMING_SNAKE_CASE								=      self.get_auto_remove_tmp_dir()
  													args_d.update(
  													    data_dir=_A   ,							model_name_or_path=_A   ,							tokenizer_name=_A   ,							train_batch_size=2   ,							eval_batch_size=2   ,							output_dir=_A   ,							do_predict=_A   ,							task=_A   ,							src_lang='en_XX'   ,							tgt_lang='ro_RO'   ,							freeze_encoder=_A   ,							freeze_embeds=_A   ,							)
  													assert "n_train" in args_d
  													__SCREAMING_SNAKE_CASE								=      argparse.Namespace(**_A	)
  													__SCREAMING_SNAKE_CASE								=      main(_A	)
  
  													__SCREAMING_SNAKE_CASE								=      module.model.get_input_embeddings()
  													assert not input_embeds.weight.requires_grad
  													if model == T5_TINY:
  																				__SCREAMING_SNAKE_CASE								=      module.model.lm_head
  																				assert not lm_head.weight.requires_grad
  																				assert (lm_head.weight == input_embeds.weight).all().item()
  													elif model == FSMT_TINY:
  																				__SCREAMING_SNAKE_CASE								=      module.model.model
  																				__SCREAMING_SNAKE_CASE								=      fsmt.decoder.embed_positions
  																				assert not embed_pos.weight.requires_grad
  																				assert not fsmt.decoder.embed_tokens.weight.requires_grad
  																				# check that embeds are not the same
  																				assert fsmt.decoder.embed_tokens != fsmt.encoder.embed_tokens
  													else:
  																				__SCREAMING_SNAKE_CASE								=      module.model.model
  																				__SCREAMING_SNAKE_CASE								=      bart.decoder.embed_positions
  																				assert not embed_pos.weight.requires_grad
  																				assert not bart.shared.weight.requires_grad
  																				# check that embeds are the same
  																				assert bart.decoder.embed_tokens == bart.encoder.embed_tokens
  																				assert bart.decoder.embed_tokens == bart.shared
  
  													__SCREAMING_SNAKE_CASE								=      load_json(module.output_dir / 'text_batch.json'	)
  													assert isinstance(_A   ,							_A	)
  													assert len(_A	) >= 4
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      CHEAP_ARGS.copy()
  
  													__SCREAMING_SNAKE_CASE								=      'summarization'
  													__SCREAMING_SNAKE_CASE								=      make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()	)
  
  													args_d.update(
  													    data_dir=_A   ,							tokenizer_name=_A   ,							train_batch_size=2   ,							eval_batch_size=2   ,							do_predict=_A   ,							task=_A   ,							src_lang='en_XX'   ,							tgt_lang='ro_RO'   ,							freeze_encoder=_A   ,							freeze_embeds=_A   ,							)
  
  													# test models whose config includes the extra_model_args
  													__SCREAMING_SNAKE_CASE								=      BART_TINY
  													__SCREAMING_SNAKE_CASE								=      self.get_auto_remove_tmp_dir()
  													__SCREAMING_SNAKE_CASE								=      args_d.copy()
  													args_da.update(
  													    model_name_or_path=_A   ,							output_dir=_A   ,							)
  													__SCREAMING_SNAKE_CASE								=      ('encoder_layerdrop', 'decoder_layerdrop', 'dropout', 'attention_dropout')
  													for p in extra_model_params:
  																				__SCREAMING_SNAKE_CASE								=      0.5
  													__SCREAMING_SNAKE_CASE								=      argparse.Namespace(**_A	)
  													__SCREAMING_SNAKE_CASE								=      main(_A	)
  													for p in extra_model_params:
  																				assert getattr(model.config   ,							_A	) == 0.5, f"""failed to override the model config for param {p}"""
  
  													# test models whose config doesn't include the extra_model_args
  													__SCREAMING_SNAKE_CASE								=      T5_TINY
  													__SCREAMING_SNAKE_CASE								=      self.get_auto_remove_tmp_dir()
  													__SCREAMING_SNAKE_CASE								=      args_d.copy()
  													args_da.update(
  													    model_name_or_path=_A   ,							output_dir=_A   ,							)
  													__SCREAMING_SNAKE_CASE								=      'encoder_layerdrop'
  													__SCREAMING_SNAKE_CASE								=      0.5
  													__SCREAMING_SNAKE_CASE								=      argparse.Namespace(**_A	)
  													with pytest.raises(_A	) as excinfo:
  																				__SCREAMING_SNAKE_CASE								=      main(_A	)
  													assert str(excinfo.value	) == f"""model config doesn't have a `{unsupported_param}` attribute"""
  
  
  
  
  
  
  						def  _A			(					self	):
  
  
  
  
  
  
  
  													'''simple docstring'''
  
  													__SCREAMING_SNAKE_CASE								=      CHEAP_ARGS.copy()
  
  													__SCREAMING_SNAKE_CASE								=      'summarization'
  													__SCREAMING_SNAKE_CASE								=      make_test_data_dir(tmp_dir=self.get_auto_remove_tmp_dir()	)
  
  													__SCREAMING_SNAKE_CASE								=      BART_TINY
  													__SCREAMING_SNAKE_CASE								=      self.get_auto_remove_tmp_dir()
  
  													args_d.update(
  													    data_dir=_A   ,							model_name_or_path=_A   ,							output_dir=_A   ,							tokenizer_name=_A   ,							train_batch_size=2   ,							eval_batch_size=2   ,							do_predict=_A   ,							task=_A   ,							src_lang='en_XX'   ,							tgt_lang='ro_RO'   ,							freeze_encoder=_A   ,							freeze_embeds=_A   ,							)
  
  													# emulate finetune.py
  													__SCREAMING_SNAKE_CASE								=      argparse.ArgumentParser()
  													__SCREAMING_SNAKE_CASE								=      pl.Trainer.add_argparse_args(_A	)
  													__SCREAMING_SNAKE_CASE								=      SummarizationModule.add_model_specific_args(_A   ,							os.getcwd()	)
  													__SCREAMING_SNAKE_CASE								=      {'--help': True}
  
  													# --help test
  													with pytest.raises(_A	) as excinfo:
  																				with CaptureStdout() as cs:
  																											__SCREAMING_SNAKE_CASE								=      parser.parse_args(_A	)
  																				assert False, "--help is expected to sys.exit"
  													assert excinfo.type == SystemExit
  													__SCREAMING_SNAKE_CASE								=      lightning_base.arg_to_scheduler_metavar
  													assert expected in cs.out, "--help is expected to list the supported schedulers"
  
  													# --lr_scheduler=non_existing_scheduler test
  													__SCREAMING_SNAKE_CASE								=      'non_existing_scheduler'
  													__SCREAMING_SNAKE_CASE								=      {f"""--lr_scheduler={unsupported_param}"""}
  													with pytest.raises(_A	) as excinfo:
  																				with CaptureStderr() as cs:
  																											__SCREAMING_SNAKE_CASE								=      parser.parse_args(_A	)
  																				assert False, "invalid argument is expected to sys.exit"
  													assert excinfo.type == SystemExit
  													__SCREAMING_SNAKE_CASE								=      f"""invalid choice: '{unsupported_param}'"""
  													assert expected in cs.err, f"""should have bailed on invalid choice of scheduler {unsupported_param}"""
  
  													# --lr_scheduler=existing_scheduler test
  													__SCREAMING_SNAKE_CASE								=      'cosine'
  													__SCREAMING_SNAKE_CASE								=      args_d.copy()
  													__SCREAMING_SNAKE_CASE								=      supported_param
  													__SCREAMING_SNAKE_CASE								=      argparse.Namespace(**_A	)
  													__SCREAMING_SNAKE_CASE								=      main(_A	)
  													assert (
  													    getattr(model.hparams   ,							'lr_scheduler'	) == supported_param
  													), f"""lr_scheduler={supported_param} shouldn't fail"""
  
  
  
  
  
  
  
style_context: 
  
  
  
  from itertools import combinations, product
  
  
  
  
  
  
  def 			__lowercase     (				a__							,     a__							,     a__							,     a__     )       ->				bool:
  							if xa == ya == 0 or xa == ya == 0:
  														return False
  							__SCREAMING_SNAKE_CASE								=      xa * xa + ya * ya
  							__SCREAMING_SNAKE_CASE								=      xa * xa + ya * ya
  							__SCREAMING_SNAKE_CASE								=      (xa - xa) * (xa - xa) + (ya - ya) * (ya - ya)
  							return (
  							    a_square + b_square == c_square
  							    or a_square + c_square == b_square
  							    or b_square + c_square == a_square
  							)
  
  
  
  
  
  
  def 			__lowercase     (				a__ = 50     )       ->				int:
  							return sum(
  							    1
  							    for pta, pta in combinations(product(range(limit + 1     )							,     repeat=2     )							,     2     )
  							    if is_right(*a__							,     *a__     )     )
  
  
  if __name__ == "__main__":
  			print(F'''{solution() = }''')
  
  
  
  
  
  
  