

import collections
import types

import numpy as np

from ..utils import (
    add_end_docstrings,
    is_tensorflow_probability_available,
    is_tf_available,
    is_torch_available,
    requires_backends,
)
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, Dataset, Pipeline, PipelineException


if is_torch_available():
  import torch

  from ..models.auto.modeling_auto import (
      MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
      MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
  )

if is_tf_available() and is_tensorflow_probability_available():
  import tensorflow as tf
  import tensorflow_probability as tfp

  from ..models.auto.modeling_tf_auto import (
      TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING,
      TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING,
  )






class 							A_			(		snake_case__ ):


     def __call__(							self      :		Optional[int]      ,  UpperCAmelCase      :		Optional[int]=None      ,  UpperCAmelCase      :		int=None      ,  **UpperCAmelCase      :		Any )							->     Union[str, Any]:
      # Returns tqa_pipeline_inputs of shape:
      # [
      #   {"table": pd.DataFrame, "query": List[str]},
      #   ...,
      #   {"table": pd.DataFrame, "query" : List[str]}
      # ]
      requires_backends(self      ,  'pandas' )
      import pandas as pd

      if table is None:
       raise ValueError('Keyword argument `table` cannot be None.' )
      elif query is None:
       if isinstance(UpperCAmelCase      ,  UpperCAmelCase ) and table.get('query' ) is not None and table.get('table' ) is not None:
        __lowerCAmelCase:       Dict            =				[table]
       elif isinstance(UpperCAmelCase      ,  UpperCAmelCase ) and len(UpperCAmelCase ) > 0:
        if not all(isinstance(UpperCAmelCase      ,  UpperCAmelCase ) for d in table ):
         raise ValueError(
             F'''Keyword argument `table` should be a list of dict, but is {(type(UpperCAmelCase ) for d in table)}''' )

        if table[0].get('query' ) is not None and table[0].get('table' ) is not None:
         __lowerCAmelCase:       List[Any]            =				table
        else:
         raise ValueError(
             'If keyword argument `table` is a list of dictionaries, each dictionary should have a `table`'
             F''' and `query` key, but only dictionary has keys {table[0].keys()} `table` and `query` keys.''' )
       elif Dataset is not None and isinstance(UpperCAmelCase      ,  UpperCAmelCase ) or isinstance(UpperCAmelCase      ,  types.GeneratorType ):
        return table
       else:
        raise ValueError(
            'Invalid input. Keyword argument `table` should be either of type `dict` or `list`, but '
            F'''is {type(UpperCAmelCase )})''' )
      else:
       __lowerCAmelCase:       Any            =				[{'table': table, 'query': query}]

      for tqa_pipeline_input in tqa_pipeline_inputs:
       if not isinstance(tqa_pipeline_input['table']      ,  pd.DataFrame ):
        if tqa_pipeline_input["table"] is None:
         raise ValueError('Table cannot be None.' )

        __lowerCAmelCase:       List[Any]            =				pd.DataFrame(tqa_pipeline_input['table'] )

      return tqa_pipeline_inputs







@add_end_docstrings(snake_case__ )
class 							A_			(		snake_case__ ):
     _lowercase      :					Optional[int]       =     'table,query'


     def __init__(							self      :		Tuple      ,  UpperCAmelCase      :		Optional[Any]=TableQuestionAnsweringArgumentHandler()      ,  *UpperCAmelCase      :		List[str]      ,  **UpperCAmelCase      :		Any )							->     int:
      super().__init__(*UpperCAmelCase      ,  **UpperCAmelCase )
      __lowerCAmelCase:       Union[str, Any]            =				args_parser

      self.check_model_type(
          dict(
              TF_MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items()
              + TF_MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items() )
          if self.framework == 'tf'
          else dict(
              MODEL_FOR_TABLE_QUESTION_ANSWERING_MAPPING.items() + MODEL_FOR_SEQ_TO_SEQ_CAUSAL_LM_MAPPING.items() ) )

      __lowerCAmelCase:       int            =				bool(getattr(self.model.config      ,  'aggregation_labels'      ,  UpperCAmelCase ) ) and bool(
          getattr(self.model.config      ,  'num_aggregation_labels'      ,  UpperCAmelCase ) )
      __lowerCAmelCase:       Optional[int]            =				'tapas' if hasattr(self.model.config      ,  'aggregation_labels' ) else None


     def   UpperCAmelCase  (							self      :		Union[str, Any]      ,  **UpperCAmelCase      :		Tuple )							->     Optional[int]:
      return self.model(**UpperCAmelCase )


     def   UpperCAmelCase  (							self      :		Any      ,  **UpperCAmelCase      :		Union[str, Any] )							->     str:
      if self.framework == "pt":
       __lowerCAmelCase:       List[Any]            =				[]
       __lowerCAmelCase:       int            =				[]
       __lowerCAmelCase:       Tuple            =				None
       __lowerCAmelCase:       Optional[Any]            =				inputs['input_ids'].shape[0]

       __lowerCAmelCase:       List[str]            =				inputs['input_ids'].to(self.device )
       __lowerCAmelCase:       Any            =				inputs['attention_mask'].to(self.device )
       __lowerCAmelCase:       Tuple            =				inputs['token_type_ids'].to(self.device )
       __lowerCAmelCase:       Union[str, Any]            =				None

       for index in range(UpperCAmelCase ):
        # If sequences have already been processed, the token type IDs will be created according to the previous
        # answer.
        if prev_answers is not None:
         __lowerCAmelCase:       List[str]            =				token_type_ids_example[:, 3]  # shape (seq_len,)
         __lowerCAmelCase:       Dict            =				np.zeros_like(prev_labels_example.cpu().numpy() )  # shape (seq_len,)

         __lowerCAmelCase:       List[Any]            =				token_type_ids[index]  # shape (seq_len, 7)
         for i in range(model_labels.shape[0] ):
          __lowerCAmelCase:       List[Any]            =				token_type_ids_example[:, 0].tolist()[i]
          __lowerCAmelCase:       Optional[int]            =				token_type_ids_example[:, 1].tolist()[i] - 1
          __lowerCAmelCase:       Optional[Any]            =				token_type_ids_example[:, 2].tolist()[i] - 1

          if row_id >= 0 and col_id >= 0 and segment_id == 1:
           __lowerCAmelCase:       Union[str, Any]            =				int(prev_answers[(col_id, row_id)] )

         __lowerCAmelCase:       str            =				torch.from_numpy(UpperCAmelCase ).type(torch.long ).to(self.device )

        __lowerCAmelCase:       Optional[int]            =				input_ids[index]
        __lowerCAmelCase:       int            =				attention_mask[index]  # shape (seq_len,)
        __lowerCAmelCase:       List[Any]            =				token_type_ids[index]  # shape (seq_len, 7)
        __lowerCAmelCase:       Any            =				self.model(
            input_ids=input_ids_example.unsqueeze(0 )      ,  attention_mask=attention_mask_example.unsqueeze(0 )      ,  token_type_ids=token_type_ids_example.unsqueeze(0 )      ,  )
        __lowerCAmelCase:       Dict            =				outputs.logits

        if self.aggregate:
         all_aggregations.append(outputs.logits_aggregation )

        all_logits.append(UpperCAmelCase )

        __lowerCAmelCase:       Tuple            =				torch.distributions.Bernoulli(logits=UpperCAmelCase )
        __lowerCAmelCase:       str            =				dist_per_token.probs * attention_mask_example.type(torch.floataa ).to(
            dist_per_token.probs.device )

        __lowerCAmelCase:       Union[str, Any]            =				collections.defaultdict(UpperCAmelCase )
        for i, p in enumerate(probabilities.squeeze().tolist() ):
         __lowerCAmelCase:       List[Any]            =				token_type_ids_example[:, 0].tolist()[i]
         __lowerCAmelCase:       Optional[Any]            =				token_type_ids_example[:, 1].tolist()[i] - 1
         __lowerCAmelCase:       Any            =				token_type_ids_example[:, 2].tolist()[i] - 1
         if col >= 0 and row >= 0 and segment_id == 1:
          coords_to_probs[(col, row)].append(UpperCAmelCase )

        __lowerCAmelCase:       int            =				{key: np.array(coords_to_probs[key] ).mean() > 0.5 for key in coords_to_probs}

       __lowerCAmelCase:       Any            =				torch.cat(tuple(UpperCAmelCase )      ,  0 )

       return (logits_batch,) if not self.aggregate else (logits_batch, torch.cat(tuple(UpperCAmelCase )      ,  0 ))
      else:
       __lowerCAmelCase:       Any            =				[]
       __lowerCAmelCase:       Tuple            =				[]
       __lowerCAmelCase:       Any            =				None
       __lowerCAmelCase:       Tuple            =				inputs['input_ids'].shape[0]

       __lowerCAmelCase:       Any            =				inputs['input_ids']
       __lowerCAmelCase:       str            =				inputs['attention_mask']
       __lowerCAmelCase:       Dict            =				inputs['token_type_ids'].numpy()
       __lowerCAmelCase:       Union[str, Any]            =				None

       for index in range(UpperCAmelCase ):
        # If sequences have already been processed, the token type IDs will be created according to the previous
        # answer.
        if prev_answers is not None:
         __lowerCAmelCase:       int            =				token_type_ids_example[:, 3]  # shape (seq_len,)
         __lowerCAmelCase:       str            =				np.zeros_like(UpperCAmelCase      ,  dtype=np.intaa )  # shape (seq_len,)

         __lowerCAmelCase:       Tuple            =				token_type_ids[index]  # shape (seq_len, 7)
         for i in range(model_labels.shape[0] ):
          __lowerCAmelCase:       Tuple            =				token_type_ids_example[:, 0].tolist()[i]
          __lowerCAmelCase:       List[Any]            =				token_type_ids_example[:, 1].tolist()[i] - 1
          __lowerCAmelCase:       Optional[Any]            =				token_type_ids_example[:, 2].tolist()[i] - 1

          if row_id >= 0 and col_id >= 0 and segment_id == 1:
           __lowerCAmelCase:       Optional[int]            =				int(prev_answers[(col_id, row_id)] )

         __lowerCAmelCase:       Union[str, Any]            =				model_labels

        __lowerCAmelCase:       Tuple            =				input_ids[index]
        __lowerCAmelCase:       List[str]            =				attention_mask[index]  # shape (seq_len,)
        __lowerCAmelCase:       Tuple            =				token_type_ids[index]  # shape (seq_len, 7)
        __lowerCAmelCase:       List[Any]            =				self.model(
            input_ids=np.expand_dims(UpperCAmelCase      ,  axis=0 )      ,  attention_mask=np.expand_dims(UpperCAmelCase      ,  axis=0 )      ,  token_type_ids=np.expand_dims(UpperCAmelCase      ,  axis=0 )      ,  )
        __lowerCAmelCase:       Optional[Any]            =				outputs.logits

        if self.aggregate:
         all_aggregations.append(outputs.logits_aggregation )

        all_logits.append(UpperCAmelCase )

        __lowerCAmelCase:       Any            =				tfp.distributions.Bernoulli(logits=UpperCAmelCase )
        __lowerCAmelCase:       Optional[Any]            =				dist_per_token.probs_parameter() * tf.cast(UpperCAmelCase      ,  tf.floataa )

        __lowerCAmelCase:       Dict            =				collections.defaultdict(UpperCAmelCase )
        __lowerCAmelCase:       Optional[Any]            =				token_type_ids_example
        for i, p in enumerate(tf.squeeze(UpperCAmelCase ).numpy().tolist() ):
         __lowerCAmelCase:       int            =				token_type_ids_example[:, 0].tolist()[i]
         __lowerCAmelCase:       List[Any]            =				token_type_ids_example[:, 1].tolist()[i] - 1
         __lowerCAmelCase:       Optional[Any]            =				token_type_ids_example[:, 2].tolist()[i] - 1
         if col >= 0 and row >= 0 and segment_id == 1:
          coords_to_probs[(col, row)].append(UpperCAmelCase )

        __lowerCAmelCase:       List[str]            =				{key: np.array(coords_to_probs[key] ).mean() > 0.5 for key in coords_to_probs}

       __lowerCAmelCase:       int            =				tf.concat(tuple(UpperCAmelCase )      ,  0 )

       return (logits_batch,) if not self.aggregate else (logits_batch, tf.concat(tuple(UpperCAmelCase )      ,  0 ))


     def __call__(							self      :		Optional[int]      ,  *UpperCAmelCase      :		Any      ,  **UpperCAmelCase      :		int )							->     str:
      __lowerCAmelCase:       Any            =				self._args_parser(*UpperCAmelCase      ,  **UpperCAmelCase )

      __lowerCAmelCase:       List[str]            =				super().__call__(UpperCAmelCase      ,  **UpperCAmelCase )
      if len(UpperCAmelCase ) == 1:
       return results[0]
      return results


     def   UpperCAmelCase  (							self      :		int      ,  UpperCAmelCase      :		Any=None      ,  UpperCAmelCase      :		str=None      ,  UpperCAmelCase      :		Tuple=None      ,  **UpperCAmelCase      :		Any )							->     List[str]:
      __lowerCAmelCase:       Any            =				{}
      if padding is not None:
       __lowerCAmelCase:       List[Any]            =				padding
      if truncation is not None:
       __lowerCAmelCase:       Union[str, Any]            =				truncation

      __lowerCAmelCase:       List[str]            =				{}
      if sequential is not None:
       __lowerCAmelCase:       Optional[Any]            =				sequential
      return preprocess_params, forward_params, {}


     def   UpperCAmelCase  (							self      :		Optional[int]      ,  UpperCAmelCase      :		Dict      ,  UpperCAmelCase      :		Optional[int]=None      ,  UpperCAmelCase      :		Dict=True      ,  UpperCAmelCase      :		Dict=None )							->     str:
      if truncation is None:
       if self.type == "tapas":
        __lowerCAmelCase:       Optional[int]            =				'drop_rows_to_fit'
       else:
        __lowerCAmelCase:       str            =				'do_not_truncate'

      __lowerCAmelCase     ,							__lowerCAmelCase:       str            =				pipeline_input['table'], pipeline_input['query']
      if table.empty:
       raise ValueError('table is empty' )
      if query is None or query == "":
       raise ValueError('query is empty' )
      __lowerCAmelCase:       Union[str, Any]            =				self.tokenizer(UpperCAmelCase      ,  UpperCAmelCase      ,  return_tensors=self.framework      ,  truncation=UpperCAmelCase      ,  padding=UpperCAmelCase )
      __lowerCAmelCase:       int            =				table
      return inputs


     def   UpperCAmelCase  (							self      :		List[str]      ,  UpperCAmelCase      :		Dict      ,  UpperCAmelCase      :		Any=False )							->     int:
      __lowerCAmelCase:       Union[str, Any]            =				model_inputs.pop('table' )

      if self.type == "tapas":
       if sequential:
        __lowerCAmelCase:       Dict            =				self.sequential_inference(**UpperCAmelCase )
       else:
        __lowerCAmelCase:       int            =				self.batch_inference(**UpperCAmelCase )
      else:
       __lowerCAmelCase:       List[Any]            =				self.model.generate(**UpperCAmelCase )
      __lowerCAmelCase:       int            =				{'model_inputs': model_inputs, 'table': table, 'outputs': outputs}
      return model_outputs


     def   UpperCAmelCase  (							self      :		Dict      ,  UpperCAmelCase      :		Any )							->     Optional[int]:
      __lowerCAmelCase:       List[str]            =				model_outputs['model_inputs']
      __lowerCAmelCase:       Dict            =				model_outputs['table']
      __lowerCAmelCase:       int            =				model_outputs['outputs']
      if self.type == "tapas":
       if self.aggregate:
        __lowerCAmelCase     ,							__lowerCAmelCase:       Dict            =				outputs[:2]
        __lowerCAmelCase:       int            =				self.tokenizer.convert_logits_to_predictions(UpperCAmelCase      ,  UpperCAmelCase      ,  UpperCAmelCase )
        __lowerCAmelCase     ,							__lowerCAmelCase:       str            =				predictions
        __lowerCAmelCase:       int            =				{i: self.model.config.aggregation_labels[pred] for i, pred in enumerate(UpperCAmelCase )}

        __lowerCAmelCase:       Dict            =				self.model.config.no_aggregation_label_index
        __lowerCAmelCase:       Optional[Any]            =				{
            i: aggregators[i] + ' > ' for i, pred in enumerate(UpperCAmelCase ) if pred != no_agg_label_index
        }
       else:
        __lowerCAmelCase:       Union[str, Any]            =				outputs[0]
        __lowerCAmelCase:       Optional[Any]            =				self.tokenizer.convert_logits_to_predictions(UpperCAmelCase      ,  UpperCAmelCase )
        __lowerCAmelCase:       List[str]            =				predictions[0]
        __lowerCAmelCase:       Union[str, Any]            =				{}
        __lowerCAmelCase:       str            =				{}
       __lowerCAmelCase:       Optional[Any]            =				[]
       for index, coordinates in enumerate(UpperCAmelCase ):
        __lowerCAmelCase:       str            =				[table.iat[coordinate] for coordinate in coordinates]
        __lowerCAmelCase:       List[Any]            =				aggregators.get(UpperCAmelCase      ,  '' )
        __lowerCAmelCase:       Optional[Any]            =				aggregators_prefix.get(UpperCAmelCase      ,  '' )
        __lowerCAmelCase:       Union[str, Any]            =				{
            'answer': aggregator_prefix + ', '.join(UpperCAmelCase ),
            'coordinates': coordinates,
            'cells': [table.iat[coordinate] for coordinate in coordinates],
        }
        if aggregator:
         __lowerCAmelCase:       Union[str, Any]            =				aggregator

        answers.append(UpperCAmelCase )
       if len(UpperCAmelCase ) == 0:
        raise PipelineException('Empty answer' )
      else:
       __lowerCAmelCase:       List[str]            =				[{'answer': answer} for answer in self.tokenizer.batch_decode(UpperCAmelCase      ,  skip_special_tokens=UpperCAmelCase )]

      return answers if len(UpperCAmelCase ) > 1 else answers[0]








def _a			(	SCREAMING_SNAKE_CASE		:      int = 10_00		)   ->   int:

 """simple docstring"""






 __lowerCAmelCase:       Union[str, Any]            =				[0, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8]
 # number of letters in twenty, thirty, ..., ninety (0 for numbers less than
 # 20 due to inconsistency in teens)
 __lowerCAmelCase:       Union[str, Any]            =				[0, 0, 6, 6, 5, 5, 5, 7, 6, 6]

 __lowerCAmelCase:       Optional[int]            =				0

 for i in range(1   , n + 1		):
  if i < 10_00:
   if i >= 1_00:
    # add number of letters for "n hundred"
    count += ones_counts[i // 1_00] + 7

    if i % 1_00 != 0:
     # add number of letters for "and" if number is not multiple
     # of 100
     count += 3

   if 0 < i % 1_00 < 20:
    # add number of letters for one, two, three, ..., nineteen
    # (could be combined with below if not for inconsistency in
    # teens)
    count += ones_counts[i % 1_00]
   else:
    # add number of letters for twenty, twenty one, ..., ninety
    # nine
    count += ones_counts[i % 10]
    count += tens_counts[(i % 1_00 - i % 10) // 10]
  else:
   count += ones_counts[i // 10_00] + 8
 return count


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





