'''simple docstring'''




import argparse
from collections import OrderedDict
from pathlib import Path

import torch
from huggingface_hub import hf_hub_download
from PIL import Image
from torchvision.transforms import functional as F

from transformers import DetrImageProcessor, TableTransformerConfig, TableTransformerForObjectDetection
from transformers.utils import logging


logging.set_verbosity_info()
__UpperCAmelCase     							=logging.get_logger(__name__)

# here we list all keys to be renamed (original name on the left, our name on the right)
__UpperCAmelCase     							=[]
for i in range(6):
  # encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
  rename_keys.append(
      (f'transformer.encoder.layers.{i}.self_attn.out_proj.weight', f'encoder.layers.{i}.self_attn.out_proj.weight')
  )
  rename_keys.append(
      (f'transformer.encoder.layers.{i}.self_attn.out_proj.bias', f'encoder.layers.{i}.self_attn.out_proj.bias')
  )
  rename_keys.append((f'transformer.encoder.layers.{i}.linear1.weight', f'encoder.layers.{i}.fc1.weight'))
  rename_keys.append((f'transformer.encoder.layers.{i}.linear1.bias', f'encoder.layers.{i}.fc1.bias'))
  rename_keys.append((f'transformer.encoder.layers.{i}.linear2.weight', f'encoder.layers.{i}.fc2.weight'))
  rename_keys.append((f'transformer.encoder.layers.{i}.linear2.bias', f'encoder.layers.{i}.fc2.bias'))
  rename_keys.append(
      (f'transformer.encoder.layers.{i}.norm1.weight', f'encoder.layers.{i}.self_attn_layer_norm.weight')
  )
  rename_keys.append((f'transformer.encoder.layers.{i}.norm1.bias', f'encoder.layers.{i}.self_attn_layer_norm.bias'))
  rename_keys.append((f'transformer.encoder.layers.{i}.norm2.weight', f'encoder.layers.{i}.final_layer_norm.weight'))
  rename_keys.append((f'transformer.encoder.layers.{i}.norm2.bias', f'encoder.layers.{i}.final_layer_norm.bias'))
  # decoder layers: 2 times output projection, 2 feedforward neural networks and 3 layernorms
  rename_keys.append(
      (f'transformer.decoder.layers.{i}.self_attn.out_proj.weight', f'decoder.layers.{i}.self_attn.out_proj.weight')
  )
  rename_keys.append(
      (f'transformer.decoder.layers.{i}.self_attn.out_proj.bias', f'decoder.layers.{i}.self_attn.out_proj.bias')
  )
  rename_keys.append(
      (
          f'transformer.decoder.layers.{i}.multihead_attn.out_proj.weight',
          f'decoder.layers.{i}.encoder_attn.out_proj.weight',
      )
  )
  rename_keys.append(
      (
          f'transformer.decoder.layers.{i}.multihead_attn.out_proj.bias',
          f'decoder.layers.{i}.encoder_attn.out_proj.bias',
      )
  )
  rename_keys.append((f'transformer.decoder.layers.{i}.linear1.weight', f'decoder.layers.{i}.fc1.weight'))
  rename_keys.append((f'transformer.decoder.layers.{i}.linear1.bias', f'decoder.layers.{i}.fc1.bias'))
  rename_keys.append((f'transformer.decoder.layers.{i}.linear2.weight', f'decoder.layers.{i}.fc2.weight'))
  rename_keys.append((f'transformer.decoder.layers.{i}.linear2.bias', f'decoder.layers.{i}.fc2.bias'))
  rename_keys.append(
      (f'transformer.decoder.layers.{i}.norm1.weight', f'decoder.layers.{i}.self_attn_layer_norm.weight')
  )
  rename_keys.append((f'transformer.decoder.layers.{i}.norm1.bias', f'decoder.layers.{i}.self_attn_layer_norm.bias'))
  rename_keys.append(
      (f'transformer.decoder.layers.{i}.norm2.weight', f'decoder.layers.{i}.encoder_attn_layer_norm.weight')
  )
  rename_keys.append(
      (f'transformer.decoder.layers.{i}.norm2.bias', f'decoder.layers.{i}.encoder_attn_layer_norm.bias')
  )
  rename_keys.append((f'transformer.decoder.layers.{i}.norm3.weight', f'decoder.layers.{i}.final_layer_norm.weight'))
  rename_keys.append((f'transformer.decoder.layers.{i}.norm3.bias', f'decoder.layers.{i}.final_layer_norm.bias'))

# convolutional projection + query embeddings + layernorm of encoder + layernorm of decoder + class and bounding box heads
rename_keys.extend(
    [
        ("input_proj.weight", "input_projection.weight"),
        ("input_proj.bias", "input_projection.bias"),
        ("query_embed.weight", "query_position_embeddings.weight"),
        ("transformer.encoder.norm.weight", "encoder.layernorm.weight"),
        ("transformer.encoder.norm.bias", "encoder.layernorm.bias"),
        ("transformer.decoder.norm.weight", "decoder.layernorm.weight"),
        ("transformer.decoder.norm.bias", "decoder.layernorm.bias"),
        ("class_embed.weight", "class_labels_classifier.weight"),
        ("class_embed.bias", "class_labels_classifier.bias"),
        ("bbox_embed.layers.0.weight", "bbox_predictor.layers.0.weight"),
        ("bbox_embed.layers.0.bias", "bbox_predictor.layers.0.bias"),
        ("bbox_embed.layers.1.weight", "bbox_predictor.layers.1.weight"),
        ("bbox_embed.layers.1.bias", "bbox_predictor.layers.1.bias"),
        ("bbox_embed.layers.2.weight", "bbox_predictor.layers.2.weight"),
        ("bbox_embed.layers.2.bias", "bbox_predictor.layers.2.bias"),
    ]
)






def __lowerCAmelCase (							UpperCamelCase__				,  UpperCamelCase__				,  UpperCamelCase__				)	->    Optional[int]:
    __lowerCamelCase		=  state_dict.pop(UpperCamelCase__				)
    __lowerCamelCase		=  val






def __lowerCAmelCase (							UpperCamelCase__				)	->    Dict:
    __lowerCamelCase		=  OrderedDict()
    for key, value in state_dict.items():
        if "backbone.0.body" in key:
            __lowerCamelCase		=  key.replace('''backbone.0.body'''				,  '''backbone.conv_encoder.model'''				)
            __lowerCamelCase		=  value
        else:
            __lowerCamelCase		=  value

    return new_state_dict






def __lowerCAmelCase (							UpperCamelCase__				)	->    Optional[Any]:
    __lowerCamelCase		=  ''''''

    # first: transformer encoder
    for i in range(6				):
        # read in weights + bias of input projection layer (in PyTorch's MultiHeadAttention, this is a single matrix + bias)
        __lowerCamelCase		=  state_dict.pop(f"""{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_weight"""				)
        __lowerCamelCase		=  state_dict.pop(f"""{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_bias"""				)
        # next, add query, keys and values (in that order) to the state dict
        __lowerCamelCase		=  in_proj_weight[:2_56, :]
        __lowerCamelCase		=  in_proj_bias[:2_56]
        __lowerCamelCase		=  in_proj_weight[2_56:5_12, :]
        __lowerCamelCase		=  in_proj_bias[2_56:5_12]
        __lowerCamelCase		=  in_proj_weight[-2_56:, :]
        __lowerCamelCase		=  in_proj_bias[-2_56:]
    # next: transformer decoder (which is a bit more complex because it also includes cross-attention)
    for i in range(6				):
        # read in weights + bias of input projection layer of self-attention
        __lowerCamelCase		=  state_dict.pop(f"""{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_weight"""				)
        __lowerCamelCase		=  state_dict.pop(f"""{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_bias"""				)
        # next, add query, keys and values (in that order) to the state dict
        __lowerCamelCase		=  in_proj_weight[:2_56, :]
        __lowerCamelCase		=  in_proj_bias[:2_56]
        __lowerCamelCase		=  in_proj_weight[2_56:5_12, :]
        __lowerCamelCase		=  in_proj_bias[2_56:5_12]
        __lowerCamelCase		=  in_proj_weight[-2_56:, :]
        __lowerCamelCase		=  in_proj_bias[-2_56:]
        # read in weights + bias of input projection layer of cross-attention
        __lowerCamelCase		=  state_dict.pop(
            f"""{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_weight"""				)
        __lowerCamelCase		=  state_dict.pop(f"""{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_bias"""				)
        # next, add query, keys and values (in that order) of cross-attention to the state dict
        __lowerCamelCase		=  in_proj_weight_cross_attn[:2_56, :]
        __lowerCamelCase		=  in_proj_bias_cross_attn[:2_56]
        __lowerCamelCase		=  in_proj_weight_cross_attn[2_56:5_12, :]
        __lowerCamelCase		=  in_proj_bias_cross_attn[2_56:5_12]
        __lowerCamelCase		=  in_proj_weight_cross_attn[-2_56:, :]
        __lowerCamelCase		=  in_proj_bias_cross_attn[-2_56:]






def __lowerCAmelCase (							UpperCamelCase__				,  UpperCamelCase__				)	->    str:
    __lowerCamelCase	,  __lowerCamelCase		=  image.size
    __lowerCamelCase		=  max(UpperCamelCase__				,  UpperCamelCase__				)
    __lowerCamelCase		=  8_00 if '''detection''' in checkpoint_url else 10_00
    __lowerCamelCase		=  target_max_size / current_max_size
    __lowerCamelCase		=  image.resize((int(round(scale * width				)				), int(round(scale * height				)				))				)

    return resized_image






def __lowerCAmelCase (							UpperCamelCase__				)	->    Tuple:
    __lowerCamelCase		=  F.to_tensor(UpperCamelCase__				)
    __lowerCamelCase		=  F.normalize(UpperCamelCase__				,  mean=[0.4_8_5, 0.4_5_6, 0.4_0_6]				,  std=[0.2_2_9, 0.2_2_4, 0.2_2_5]				)
    return image






@torch.no_grad()
def __lowerCAmelCase (							UpperCamelCase__				,  UpperCamelCase__				,  UpperCamelCase__				)	->    Dict:
    logger.info('''Converting model...'''				)

    # load original state dict
    __lowerCamelCase		=  torch.hub.load_state_dict_from_url(UpperCamelCase__				,  map_location='''cpu'''				)
    # rename keys
    for src, dest in rename_keys:
        rename_key(UpperCamelCase__				,  UpperCamelCase__				,  UpperCamelCase__				)
    __lowerCamelCase		=  rename_backbone_keys(UpperCamelCase__				)
    # query, key and value matrices need special treatment
    read_in_q_k_v(UpperCamelCase__				)
    # important: we need to prepend a prefix to each of the base model keys as the head models use different attributes for them
    __lowerCamelCase		=  '''model.'''
    for key in state_dict.copy().keys():
        if not key.startswith('''class_labels_classifier'''				) and not key.startswith('''bbox_predictor'''				):
            __lowerCamelCase		=  state_dict.pop(UpperCamelCase__				)
            __lowerCamelCase		=  val
    # create HuggingFace model and load state dict
    __lowerCamelCase		=  TableTransformerConfig(
        backbone='''resnet18'''				,  mask_loss_coefficient=1				,  dice_loss_coefficient=1				,  ce_loss_coefficient=1				,  bbox_loss_coefficient=5				,  giou_loss_coefficient=2				,  eos_coefficient=0.4				,  class_cost=1				,  bbox_cost=5				,  giou_cost=2				,  )

    if "detection" in checkpoint_url:
        __lowerCamelCase		=  15
        __lowerCamelCase		=  2
        __lowerCamelCase		=  {0: '''table''', 1: '''table rotated'''}
        __lowerCamelCase		=  idalabel
        __lowerCamelCase		=  {v: k for k, v in idalabel.items()}
    else:
        __lowerCamelCase		=  1_25
        __lowerCamelCase		=  6
        __lowerCamelCase		=  {
            0: '''table''',
            1: '''table column''',
            2: '''table row''',
            3: '''table column header''',
            4: '''table projected row header''',
            5: '''table spanning cell''',
        }
        __lowerCamelCase		=  idalabel
        __lowerCamelCase		=  {v: k for k, v in idalabel.items()}

    __lowerCamelCase		=  DetrImageProcessor(
        format='''coco_detection'''				,  max_size=8_00 if '''detection''' in checkpoint_url else 10_00				)
    __lowerCamelCase		=  TableTransformerForObjectDetection(UpperCamelCase__				)
    model.load_state_dict(UpperCamelCase__				)
    model.eval()

    # verify our conversion
    __lowerCamelCase		=  '''example_pdf.png''' if '''detection''' in checkpoint_url else '''example_table.png'''
    __lowerCamelCase		=  hf_hub_download(repo_id='''nielsr/example-pdf'''				,  repo_type='''dataset'''				,  filename=UpperCamelCase__				)
    __lowerCamelCase		=  Image.open(UpperCamelCase__				).convert('''RGB'''				)
    __lowerCamelCase		=  normalize(resize(UpperCamelCase__				,  UpperCamelCase__				)				).unsqueeze(0				)

    __lowerCamelCase		=  model(UpperCamelCase__				)

    if "detection" in checkpoint_url:
        __lowerCamelCase		=  (1, 15, 3)
        __lowerCamelCase		=  torch.tensor(
            [[-6.7_8_9_7, -1_6.9_9_8_5, 6.7_9_3_7], [-8.0_1_8_6, -2_2.2_1_9_2, 6.9_6_7_7], [-7.3_1_1_7, -2_1.0_7_0_8, 7.4_0_5_5]]				)
        __lowerCamelCase		=  torch.tensor([[0.4_8_6_7, 0.1_7_6_7, 0.6_7_3_2], [0.6_7_1_8, 0.4_4_7_9, 0.3_8_3_0], [0.4_7_1_6, 0.1_7_6_0, 0.6_3_6_4]]				)

    else:
        __lowerCamelCase		=  (1, 1_25, 7)
        __lowerCamelCase		=  torch.tensor(
            [[-1_8.1_4_3_0, -8.3_2_1_4, 4.8_2_7_4], [-1_8.4_6_8_5, -7.1_3_6_1, -4.2_6_6_7], [-2_6.3_6_9_3, -9.3_4_2_9, -4.9_9_6_2]]				)
        __lowerCamelCase		=  torch.tensor([[0.4_9_8_3, 0.5_5_9_5, 0.9_4_4_0], [0.4_9_1_6, 0.6_3_1_5, 0.5_9_5_4], [0.6_1_0_8, 0.8_6_3_7, 0.1_1_3_5]]				)

    assert outputs.logits.shape == expected_shape
    assert torch.allclose(outputs.logits[0, :3, :3]				,  UpperCamelCase__				,  atol=1E-4				)
    assert torch.allclose(outputs.pred_boxes[0, :3, :3]				,  UpperCamelCase__				,  atol=1E-4				)
    print('''Looks ok!'''				)

    if pytorch_dump_folder_path is not None:
        # Save model and image processor
        logger.info(f"""Saving PyTorch model and image processor to {pytorch_dump_folder_path}..."""				)
        Path(UpperCamelCase__				).mkdir(exist_ok=UpperCamelCase__				)
        model.save_pretrained(UpperCamelCase__				)
        image_processor.save_pretrained(UpperCamelCase__				)

    if push_to_hub:
        # Push model to HF hub
        logger.info('''Pushing model to the hub...'''				)
        __lowerCamelCase		=  (
            '''microsoft/table-transformer-detection'''
            if '''detection''' in checkpoint_url
            else '''microsoft/table-transformer-structure-recognition'''
        )
        model.push_to_hub(UpperCamelCase__				)
        image_processor.push_to_hub(UpperCamelCase__				)


if __name__ == "__main__":
  __UpperCAmelCase     							=argparse.ArgumentParser()

  parser.add_argument(
      "--checkpoint_url",
      default="https://pubtables1m.blob.core.windows.net/model/pubtables1m_detection_detr_r18.pth",
      type=str,
      choices=[
          "https://pubtables1m.blob.core.windows.net/model/pubtables1m_detection_detr_r18.pth",
          "https://pubtables1m.blob.core.windows.net/model/pubtables1m_structure_detr_r18.pth",
      ],
      help="URL of the Table Transformer checkpoint you'd like to convert.",
  )
  parser.add_argument(
      "--pytorch_dump_folder_path", default=None, type=str, help="Path to the folder to output PyTorch model."
  )
  parser.add_argument(
      "--push_to_hub", action="store_true", help="Whether or not to push the converted model to the 🤗 hub."
  )
  __UpperCAmelCase     							=parser.parse_args()
  convert_table_transformer_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path, args.push_to_hub)

"""simple docstring"""






def SCREAMING_SNAKE_CASE__			(   __UpperCAmelCase )  ->  int:
   if n == 1 or not isinstance(__UpperCAmelCase       ,    __UpperCAmelCase ):
      return 0
   elif n == 2:
      return 1
   else:
      lowercase__:   List[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:
   lowercase__:   Union[str, Any]					=      0
   lowercase__:   List[Any]					=      2

   while digits < n:
      index += 1
      lowercase__:   Dict					=      len(str(fibonacci(__UpperCAmelCase ) ) )

   return index



def SCREAMING_SNAKE_CASE__			(   __UpperCAmelCase = 1_0_0_0 )  ->  int:
   return fibonacci_digits_index(__UpperCAmelCase )


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