






import os
from typing import List, Union

import tensorflow as tf
from tensorflow_text import BertTokenizer as BertTokenizerLayer
from tensorflow_text import FastBertTokenizer, ShrinkLongestTrimmer, case_fold_utfa, combine_segments, pad_model_inputs

from .tokenization_bert import BertTokenizer


class 			__SCREAMING_SNAKE_CASE    (      tf.keras.layers.Layer):






						def __init__(		self   ,  _UpperCamelCase   ,  _UpperCamelCase   ,  _UpperCamelCase = None   ,  _UpperCamelCase = None   ,  _UpperCamelCase = None   ,  _UpperCamelCase = "longest"   ,  _UpperCamelCase = True   ,  _UpperCamelCase = 5_12   ,  _UpperCamelCase = None   ,  _UpperCamelCase = True   ,  _UpperCamelCase = True   ,  _UpperCamelCase = True   ,  **_UpperCamelCase   ,  ):






												"""simple docstring"""
												super().__init__()
												if use_fast_bert_tokenizer:
																		lowerCAmelCase__			  =  FastBertTokenizer(
																		    _UpperCamelCase   ,  token_out_type=tf.intaa   ,  lower_case_nfd_strip_accents=_UpperCamelCase   ,  **_UpperCamelCase      )
												else:
																		lowerCAmelCase__			  =  tf.lookup.StaticVocabularyTable(
																		    tf.lookup.KeyValueTensorInitializer(
																		        keys=_UpperCamelCase   ,  key_dtype=tf.string   ,  values=tf.range(tf.size(_UpperCamelCase   ,  out_type=tf.intaa      )   ,  dtype=tf.intaa      )   ,  value_dtype=tf.intaa   ,  )   ,  num_oov_buckets=1   ,  )
																		lowerCAmelCase__			  =  BertTokenizerLayer(
																		    _UpperCamelCase   ,  token_out_type=tf.intaa   ,  lower_case=_UpperCamelCase   ,  **_UpperCamelCase      )

												lowerCAmelCase__			  =  vocab_list
												lowerCAmelCase__			  =  do_lower_case
												lowerCAmelCase__			  =  cls_token_id or vocab_list.index('[CLS]'      )
												lowerCAmelCase__			  =  sep_token_id or vocab_list.index('[SEP]'      )
												lowerCAmelCase__			  =  pad_token_id or vocab_list.index('[PAD]'      )
												lowerCAmelCase__			  =  ShrinkLongestTrimmer(max_length - 3   ,  axis=1      )  # Allow room for special tokens
												lowerCAmelCase__			  =  max_length
												lowerCAmelCase__			  =  padding
												lowerCAmelCase__			  =  truncation
												lowerCAmelCase__			  =  pad_to_multiple_of
												lowerCAmelCase__			  =  return_token_type_ids
												lowerCAmelCase__			  =  return_attention_mask






						@classmethod
						def 					UpperCamelCase__					(		cls   ,  _UpperCamelCase   ,  **_UpperCamelCase      ):  # noqa: F821






												"""simple docstring"""
												lowerCAmelCase__			  =  kwargs.pop('do_lower_case'   ,  _UpperCamelCase      )
												lowerCAmelCase__			  =  tokenizer.do_lower_case if do_lower_case is None else do_lower_case
												lowerCAmelCase__			  =  kwargs.pop('cls_token_id'   ,  _UpperCamelCase      )
												lowerCAmelCase__			  =  tokenizer.cls_token_id if cls_token_id is None else cls_token_id
												lowerCAmelCase__			  =  kwargs.pop('sep_token_id'   ,  _UpperCamelCase      )
												lowerCAmelCase__			  =  tokenizer.sep_token_id if sep_token_id is None else sep_token_id
												lowerCAmelCase__			  =  kwargs.pop('pad_token_id'   ,  _UpperCamelCase      )
												lowerCAmelCase__			  =  tokenizer.pad_token_id if pad_token_id is None else pad_token_id

												lowerCAmelCase__			  =  tokenizer.get_vocab()
												lowerCAmelCase__			  =  sorted([(wordpiece, idx) for wordpiece, idx in vocab.items()]   ,  key=lambda _UpperCamelCase      : x[1]      )
												lowerCAmelCase__			  =  [entry[0] for entry in vocab]
												return cls(
												    vocab_list=_UpperCamelCase   ,  do_lower_case=_UpperCamelCase   ,  cls_token_id=_UpperCamelCase   ,  sep_token_id=_UpperCamelCase   ,  pad_token_id=_UpperCamelCase   ,  **_UpperCamelCase   ,  )






						@classmethod
						def 					UpperCamelCase__					(		cls   ,  _UpperCamelCase   ,  *_UpperCamelCase   ,  **_UpperCamelCase      ):






												"""simple docstring"""
												try:
																		lowerCAmelCase__			  =  BertTokenizer.from_pretrained(_UpperCamelCase   ,  *_UpperCamelCase   ,  **_UpperCamelCase      )
												except:  # noqa: E722
																		from .tokenization_bert_fast import BertTokenizerFast

																		lowerCAmelCase__			  =  BertTokenizerFast.from_pretrained(_UpperCamelCase   ,  *_UpperCamelCase   ,  **_UpperCamelCase      )
												return cls.from_tokenizer(_UpperCamelCase   ,  **_UpperCamelCase      )






						def 					UpperCamelCase__					(		self   ,  _UpperCamelCase      ):






												"""simple docstring"""
												if self.do_lower_case:
																		lowerCAmelCase__			  =  case_fold_utfa(_UpperCamelCase      )
												lowerCAmelCase__			  =  self.tf_tokenizer.tokenize(_UpperCamelCase      )
												return tokens.merge_dims(1   ,  -1      )






						def 					UpperCamelCase__					(		self   ,  _UpperCamelCase   ,  _UpperCamelCase=None   ,  _UpperCamelCase=None   ,  _UpperCamelCase=None   ,  _UpperCamelCase=None   ,  _UpperCamelCase=None   ,  _UpperCamelCase=None   ,  _UpperCamelCase=None   ,  ):






												"""simple docstring"""
												if padding is None:
																		lowerCAmelCase__			  =  self.padding
												if padding not in ("longest", "max_length"):
																		raise ValueError('Padding must be either \'longest\' or \'max_length\'!'      )
												if max_length is not None and text_pair is not None:
																		# Because we have to instantiate a Trimmer to do it properly
																		raise ValueError('max_length cannot be overridden at call time when truncating paired texts!'      )
												if max_length is None:
																		lowerCAmelCase__			  =  self.max_length
												if truncation is None:
																		lowerCAmelCase__			  =  self.truncation
												if pad_to_multiple_of is None:
																		lowerCAmelCase__			  =  self.pad_to_multiple_of
												if return_token_type_ids is None:
																		lowerCAmelCase__			  =  self.return_token_type_ids
												if return_attention_mask is None:
																		lowerCAmelCase__			  =  self.return_attention_mask
												if not isinstance(_UpperCamelCase   ,  tf.Tensor      ):
																		lowerCAmelCase__			  =  tf.convert_to_tensor(_UpperCamelCase      )
												if text_pair is not None and not isinstance(_UpperCamelCase   ,  tf.Tensor      ):
																		lowerCAmelCase__			  =  tf.convert_to_tensor(_UpperCamelCase      )
												if text_pair is not None:
																		if text.shape.rank > 1:
																								raise ValueError('text argument should not be multidimensional when a text pair is supplied!'      )
																		if text_pair.shape.rank > 1:
																								raise ValueError('text_pair should not be multidimensional!'      )
												if text.shape.rank == 2:
																		lowerCAmelCase__  ,				lowerCAmelCase__			  =  text[:, 0], text[:, 1]
												lowerCAmelCase__			  =  self.unpaired_tokenize(_UpperCamelCase      )
												if text_pair is None:  # Unpaired text
																		if truncation:
																								lowerCAmelCase__			  =  text[:, : max_length - 2]  # Allow room for special tokens
																		lowerCAmelCase__  ,				lowerCAmelCase__			  =  combine_segments(
																		    (text,)   ,  start_of_sequence_id=self.cls_token_id   ,  end_of_segment_id=self.sep_token_id      )
												else:  # Paired text
																		lowerCAmelCase__			  =  self.unpaired_tokenize(_UpperCamelCase      )
																		if truncation:
																								lowerCAmelCase__  ,				lowerCAmelCase__			  =  self.paired_trimmer.trim([text, text_pair]      )
																		lowerCAmelCase__  ,				lowerCAmelCase__			  =  combine_segments(
																		    (text, text_pair)   ,  start_of_sequence_id=self.cls_token_id   ,  end_of_segment_id=self.sep_token_id      )
												if padding == "longest":
																		lowerCAmelCase__			  =  input_ids.bounding_shape(axis=1      )
																		if pad_to_multiple_of is not None:
																								# No ceiling division in tensorflow, so we negate floordiv instead
																								lowerCAmelCase__			  =  pad_to_multiple_of * (-tf.math.floordiv(-pad_length   ,  _UpperCamelCase      ))
												else:
																		lowerCAmelCase__			  =  max_length

												lowerCAmelCase__  ,				lowerCAmelCase__			  =  pad_model_inputs(_UpperCamelCase   ,  max_seq_length=_UpperCamelCase   ,  pad_value=self.pad_token_id      )
												lowerCAmelCase__			  =  {'input_ids': input_ids}
												if return_attention_mask:
																		lowerCAmelCase__			  =  attention_mask
												if return_token_type_ids:
																		lowerCAmelCase__  ,				lowerCAmelCase__			  =  pad_model_inputs(
																		    _UpperCamelCase   ,  max_seq_length=_UpperCamelCase   ,  pad_value=self.pad_token_id      )
																		lowerCAmelCase__			  =  token_type_ids
												return output







						def 					UpperCamelCase__					(		self      ):






												"""simple docstring"""
												return {
												    "vocab_list": self.vocab_list,
												    "do_lower_case": self.do_lower_case,
												    "cls_token_id": self.cls_token_id,
												    "sep_token_id": self.sep_token_id,
												    "pad_token_id": self.pad_token_id,
												}













def 		_UpperCamelCase      (			UpperCamelCase_				:    str						)     ->      int:

						"""simple docstring"""



						lowerCAmelCase__			  =  len(UpperCamelCase_						)
						lowerCAmelCase__			  =  [0] * length
						lowerCAmelCase__			  =  [[False for i in range(UpperCamelCase_						)] for j in range(UpperCamelCase_						)]
						for i, c in enumerate(UpperCamelCase_						):
												lowerCAmelCase__			  =  i
												for j in range(i + 1						):
																		if c == string[j] and (i - j < 2 or is_palindromic[j + 1][i - 1]):
																								lowerCAmelCase__			  =  True
																								lowerCAmelCase__			  =  min(UpperCamelCase_			,				0 if j == 0 else (cut[j - 1] + 1)						)
												lowerCAmelCase__			  =  mincut
						return cut[length - 1]


if __name__ == "__main__":
					__snake_case			:			Optional[Any]			   =   input("""Enter the string: """).strip()
					__snake_case			:			List[Any]			   =   find_minimum_partitions(s)
					print(f'Minimum number of partitions required for the \'{s}\' is {ans}')





