from sentence_transformers import SentenceTransformer, LoggingHandler
import torch
from myDataset import *
from src.utils import KNNOverGenBatchBleuEvaluator

device = 'cuda' if torch.cuda.is_available() else 'cpu'

logging.basicConfig(format='%(asctime)s - %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    level=logging.INFO,
                    handlers=[LoggingHandler()])
logger = logging.getLogger(__name__)

def process_anchors(path, overgen_score_path, greedy_score_path, context_window=3, num_of_anchors=1000):
    f = open(path)
    dataset = json.load(f)
    f.close()

    f = open(overgen_score_path)
    scores = json.load(f)
    f.close()

    greedy_score_path = greedy_score_path
    f = open(greedy_score_path)
    greedy_scores = json.load(f)
    f.close()

    assert len(scores) == len(dataset)
    assert len(dataset[0]["over_gen"]) == len(scores[0])

    assert len(dataset) > num_of_anchors

    lex_delex_utt_map = load_damd_lex_delex_map()

    anchor_samples = []

    for entry, score, greedy_score in zip(dataset[-num_of_anchors:], scores[-num_of_anchors:],
                                        greedy_scores[-num_of_anchors:]):

        gold_delex = entry["resp_text"]
        over_gen_list_delex = entry["over_gen"]
        context_lex = entry["context_text"]

        context_delex = list(map(lambda x: lex_delex_utt_map[x], context_lex))
        sentc = str(" <turn_sep> ".join(context_delex[0 if context_window is None else -context_window:]))
        sentr = gold_delex
        sentn_list = list(map(lambda x: x.replace(" <eos_r>", ""), over_gen_list_delex))

        positive_list = []
        negative_list = []

        for i in range(len(sentn_list)):
            if (score[i] >= greedy_score):
                positive_list.append((sentc + " <turn_sep> " + sentn_list[i], 1))
            else:
                negative_list.append((sentc + " <turn_sep> " + sentn_list[i], 0))
        num_to_added = min(len(positive_list), len(negative_list))

        anchor_samples.extend(positive_list[:num_to_added])
        anchor_samples.extend(negative_list[:num_to_added])

    return anchor_samples

'''
Main function here
'''

def run_experiment():

    context_window = 3

    knn_k = [5000]

    num_of_anchors = [5000]

    anchor_sample_list = []

    for num_anchor in num_of_anchors:
        anchor_samples = process_anchors(path="./data/0.7_train.json",
                                         overgen_score_path="./data/sim_score_mpnet_train_0.7.json",
                                         greedy_score_path="./data/sim_score_mpnet_train_0.7_greedy.json",
                                          context_window=context_window, num_of_anchors=num_anchor)

        assert len(anchor_samples) > 0
        anchor_sample_list.append((num_anchor, anchor_samples))

    init_model_path = "./output/similarity-mintl-ct-3-BatchAllTripletLoss-e5-bs128-seed42-0.7_mpnet/"

    model = SentenceTransformer(init_model_path)

    for anchor_num, anchor_sample in anchor_sample_list:
        evaluator_test = KNNOverGenBatchBleuEvaluator(data_path="./data/0.7_test.json", context_window=context_window,
                                                     anchor_samples=anchor_sample,
                                                     knn_k=knn_k, num_of_anchors=anchor_num)
        evaluator_test.__call__(model)

def main():
    run_experiment()

if __name__ == '__main__':
    main()


from django.urls import path
from blog_board.views import *
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('', BlogListView.as_view(), name='blog_list'),
    path('<int:blog_id>/', detail_blog, name='blog_view'),
    path('create/', CreateBlogView.as_view(), name='blog_creation'),
    path('create/from_csv/', CreateBlogFromCSV.as_view(), name='blog_csv_creation'),
    path('<int:blog_id>/add_com/', CreateCommentView.as_view(), name='comment_creation'),
    path('<int:blog_id>/edit_com/<int:comm_id>/', EditCommentView.as_view(), name='edit_comment'),
]+ static(
        settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
    )

#конструкция +static... помогает корректно обрабатывать ссылки на файлы


# https://adventofcode.com/2015/day/14

RACE_DURATION = 2503

def part1(input_file):
  with open(input_file, "r") as f:
    lines = f.read().strip().split("\n")

    reindeers = []
    distances = []

    for line in lines:
      line_parts = line.split(" ")

      reindeer = {}

      reindeer["speed"] = int(line_parts[3])
      reindeer["fly_duration"] = int(line_parts[6])
      reindeer["resting_duration"] = int(line_parts[-2])

      reindeers.append(reindeer)

    for reindeer in reindeers:
      state = 1 #1 - flying, 0 - resting
      distance = 0
      fly_timer = 0
      rest_timer = 0

      for _ in range(RACE_DURATION):
        if state == 1:
          distance += reindeer["speed"]
          fly_timer += 1
          if fly_timer >= reindeer["fly_duration"]:
            state = 0
            fly_timer = 0
        elif state == 0:
          rest_timer += 1
          if rest_timer >= reindeer["resting_duration"]:
            state = 1
            rest_timer = 0

      distances.append(distance)

    return max(distances)

def main():
	input_file = "day14-input.txt"
	print(part1(input_file))

if __name__ == "__main__":
	main()


from spacy.language import Language
from spacy.matcher import Matcher

from .components.base import Masker
from .components.base import mask_decorator

@Language.factory("cash_mask")
class CashMasker(Masker):
    def __init__(self, nlp, name):
        super().__init__(nlp, name)
        self.matcher = make_cash_matcher(nlp)

    @mask_decorator
    def __call__(self, doc):
        masked_tokens = list()

        matches = self.matcher(doc)
        for match_id, start, end in matches:
            tokens = [token for token in doc[start:end] if not token._.priv_currency]
            masked_tokens = masked_tokens + tokens

        cash_tokens = search_with_key_words(doc)
        masked_tokens = masked_tokens+cash_tokens
        return masked_tokens

def search_with_key_words(doc):
    out_tokens = list()
    phrases = doc._.priv_nominal_phrases
    for phrase in phrases:
        num_tokens = list()
        cash_token_flag = False
        for token in phrase:
            if token._.priv_currency:
                cash_token_flag = True
            elif token._.priv_number:
                num_tokens.append(token)
        if cash_token_flag:
            out_tokens = out_tokens+num_tokens
    return out_tokens

def make_cash_matcher(nlp):
    matcher = Matcher(nlp.vocab)
    matcher.add("Rule", [
            [{'_': {'priv_number': True}, 'OP': '+'}, {'_': {'priv_currency': True}}],
    ])
    return matcher


import copy

from tensorflow.python.profiler import tfprof_logger
from tensorflow.python.util.tf_export import tf_export

@tf_export(v1=['profiler.ProfileOptionBuilder'])
class ProfileOptionBuilder(object):
  # pylint: disable=line-too-long
  """Option Builder for Profiling API.

  For tutorial on the options, see
  https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/profiler/g3doc/options.md

  ```python
  # Users can use pre-built options:
  opts = (
      tf.profiler.ProfileOptionBuilder.trainable_variables_parameter())

  # Or, build your own options:
  opts = (tf.compat.v1.profiler.ProfileOptionBuilder()
      .with_max_depth(10)
      .with_min_micros(1000)
      .select(['accelerator_micros'])
      .with_stdout_output()
      .build()

  # Or customize the pre-built options:
  opts = (tf.compat.v1.profiler.ProfileOptionBuilder(
      tf.profiler.ProfileOptionBuilder.time_and_memory())
      .with_displaying_options(show_name_regexes=['.*rnn.*'])
      .build())

  # Finally, profiling with the options:
  _ = tf.compat.v1.profiler.profile(tf.compat.v1.get_default_graph(),
                          run_meta=run_meta,
                          cmd='scope',
                          options=opts)
  ```
  """
  # pylint: enable=line-too-long

  def __init__(self, options=None):
    """Constructor.

    Args:
      options: Optional initial option dict to start with.
    """
    if options is not None:
      self._options = copy.deepcopy(options)
    else:
      self._options = {'max_depth': 100,
                       'min_bytes': 0,
                       'min_micros': 0,
                       'min_params': 0,
                       'min_float_ops': 0,
                       'min_occurrence': 0,
                       'order_by': 'name',
                       'account_type_regexes': ['.*'],
                       'start_name_regexes': ['.*'],
                       'trim_name_regexes': [],
                       'show_name_regexes': ['.*'],
                       'hide_name_regexes': [],
                       'account_displayed_op_only': False,
                       'select': ['micros'],
                       'step': -1,
                       'output': 'stdout'}

  @staticmethod
  def trainable_variables_parameter():
    """Options used to profile trainable variable parameters.

    Normally used together with 'scope' view.

    Returns:
      A dict of profiling options.
    """
    return {'max_depth': 10000,
            'min_bytes': 0,
            'min_micros': 0,
            'min_params': 0,
            'min_float_ops': 0,
            'min_occurrence': 0,
            'order_by': 'name',
            'account_type_regexes': [tfprof_logger.TRAINABLE_VARIABLES],
            'start_name_regexes': ['.*'],
            'trim_name_regexes': [],
            'show_name_regexes': ['.*'],
            'hide_name_regexes': [],
            'account_displayed_op_only': True,
            'select': ['params'],
            'step': -1,
            'output': 'stdout'}

  @staticmethod
  def float_operation():
    # pylint: disable=line-too-long
    """Options used to profile float operations.

    Please see https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/profiler/g3doc/profile_model_architecture.md
    on the caveats of calculating float operations.

    Returns:
      A dict of profiling options.
    """
    # pylint: enable=line-too-long
    return {'max_depth': 10000,
            'min_bytes': 0,
            'min_micros': 0,
            'min_params': 0,
            'min_float_ops': 1,
            'min_occurrence': 0,
            'order_by': 'float_ops',
            'account_type_regexes': ['.*'],
            'start_name_regexes': ['.*'],
            'trim_name_regexes': [],
            'show_name_regexes': ['.*'],
            'hide_name_regexes': [],
            'account_displayed_op_only': True,
            'select': ['float_ops'],
            'step': -1,
            'output': 'stdout'}

  @staticmethod
  def time_and_memory(min_micros=1, min_bytes=1, min_accelerator_micros=0,
                      min_cpu_micros=0, min_peak_bytes=0, min_residual_bytes=0,
                      min_output_bytes=0):
    """Show operation time and memory consumptions.

    Args:
      min_micros: Only show profiler nodes with execution time
          no less than this. It sums accelerator and cpu times.
      min_bytes: Only show profiler nodes requested to allocate no less bytes
          than this.
      min_accelerator_micros: Only show profiler nodes spend no less than
          this time on accelerator (e.g. GPU).
      min_cpu_micros: Only show profiler nodes spend no less than
          this time on cpu.
      min_peak_bytes: Only show profiler nodes using no less than this bytes
          at peak (high watermark). For profiler nodes consist of multiple
          graph nodes, it sums the graph nodes' peak_bytes.
      min_residual_bytes: Only show profiler nodes have no less than
          this bytes not being de-allocated after Compute() ends. For
          profiler nodes consist of multiple graph nodes, it sums the
          graph nodes' residual_bytes.
      min_output_bytes: Only show profiler nodes have no less than this bytes
          output. The output are not necessarily allocated by this profiler
          nodes.
    Returns:
      A dict of profiling options.
    """
    return {'max_depth': 10000,
            'min_bytes': min_bytes,
            'min_peak_bytes': min_peak_bytes,
            'min_residual_bytes': min_residual_bytes,
            'min_output_bytes': min_output_bytes,
            'min_micros': min_micros,
            'min_accelerator_micros': min_accelerator_micros,
            'min_cpu_micros': min_cpu_micros,
            'min_params': 0,
            'min_float_ops': 0,
            'min_occurrence': 0,
            'order_by': 'micros',
            'account_type_regexes': ['.*'],
            'start_name_regexes': ['.*'],
            'trim_name_regexes': [],
            'show_name_regexes': ['.*'],
            'hide_name_regexes': [],
            'account_displayed_op_only': True,
            'select': ['micros', 'bytes'],
            'step': -1,
            'output': 'stdout'}

  def build(self):
    """Build a profiling option.

    Returns:
      A dict of profiling options.
    """
    return copy.deepcopy(self._options)

  def with_max_depth(self, max_depth):
    """Set the maximum depth of display.

    The depth depends on profiling view. For 'scope' view, it's the
    depth of name scope hierarchy (tree), for 'op' view, it's the number
    of operation types (list), etc.

    Args:
      max_depth: Maximum depth of the data structure to display.
    Returns:
      self
    """
    self._options['max_depth'] = max_depth
    return self

  def with_min_memory(self,
                      min_bytes=0,
                      min_peak_bytes=0,
                      min_residual_bytes=0,
                      min_output_bytes=0):
    """Only show profiler nodes consuming no less than 'min_bytes'.

    Args:
      min_bytes: Only show profiler nodes requested to allocate no less bytes
          than this.
      min_peak_bytes: Only show profiler nodes using no less than this bytes
          at peak (high watermark). For profiler nodes consist of multiple
          graph nodes, it sums the graph nodes' peak_bytes.
      min_residual_bytes: Only show profiler nodes have no less than
          this bytes not being de-allocated after Compute() ends. For
          profiler nodes consist of multiple graph nodes, it sums the
          graph nodes' residual_bytes.
      min_output_bytes: Only show profiler nodes have no less than this bytes
          output. The output are not necessarily allocated by this profiler
          nodes.
    Returns:
      self
    """
    self._options['min_bytes'] = min_bytes
    self._options['min_peak_bytes'] = min_peak_bytes
    self._options['min_residual_bytes'] = min_residual_bytes
    self._options['min_output_bytes'] = min_output_bytes
    return self

  def with_min_execution_time(self,
                              min_micros=0,
                              min_accelerator_micros=0,
                              min_cpu_micros=0):
    """Only show profiler nodes consuming no less than 'min_micros'.

    Args:
      min_micros: Only show profiler nodes with execution time
          no less than this. It sums accelerator and cpu times.
      min_accelerator_micros: Only show profiler nodes spend no less than
          this time on accelerator (e.g. GPU).
      min_cpu_micros: Only show profiler nodes spend no less than
          this time on cpu.
    Returns:
      self
    """
    self._options['min_micros'] = min_micros
    self._options['min_accelerator_micros'] = min_accelerator_micros
    self._options['min_cpu_micros'] = min_cpu_micros
    return self

  def with_min_parameters(self, min_params):
    """Only show profiler nodes holding no less than 'min_params' parameters.

    'Parameters' normally refers the weights of in TensorFlow variables.
    It reflects the 'capacity' of models.

    Args:
      min_params: Only show profiler nodes holding number parameters
          no less than this.
    Returns:
      self
    """
    self._options['min_params'] = min_params
    return self

  def with_min_occurrence(self, min_occurrence):
    # pylint: disable=line-too-long
    """Only show profiler nodes including no less than 'min_occurrence' graph nodes.

    A "node" means a profiler output node, which can be a python line
    (code view), an operation type (op view), or a graph node
    (graph/scope view). A python line includes all graph nodes created by that
    line, while an operation type includes all graph nodes of that type.

    Args:
      min_occurrence: Only show nodes including no less than this.
    Returns:
      self
    """
    # pylint: enable=line-too-long
    self._options['min_occurrence'] = min_occurrence
    return self

  def with_min_float_operations(self, min_float_ops):
    # pylint: disable=line-too-long
    """Only show profiler nodes consuming no less than 'min_float_ops'.

    Please see https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/profiler/g3doc/profile_model_architecture.md
    on the caveats of calculating float operations.

    Args:
      min_float_ops: Only show profiler nodes with float operations
          no less than this.
    Returns:
      self
    """
    # pylint: enable=line-too-long
    self._options['min_float_ops'] = min_float_ops
    return self

  def with_accounted_types(self, account_type_regexes):
    """Selectively counting statistics based on node types.

    Here, 'types' means the profiler nodes' properties. Profiler by default
    consider device name (e.g. /job:xx/.../device:GPU:0) and operation type
    (e.g. MatMul) as profiler nodes' properties. User can also associate
    customized 'types' to profiler nodes through OpLogProto proto.

    For example, user can select profiler nodes placed on gpu:0 with:
    `account_type_regexes=['.*gpu:0.*']`

    If none of a node's properties match the specified regexes, the node is
    not displayed nor accounted.

    Args:
      account_type_regexes: A list of regexes specifying the types.
    Returns:
      self.
    """
    self._options['account_type_regexes'] = copy.copy(account_type_regexes)
    return self

  def with_node_names(self,
                      start_name_regexes=None,
                      show_name_regexes=None,
                      hide_name_regexes=None,
                      trim_name_regexes=None):
    """Regular expressions used to select profiler nodes to display.

    After 'with_accounted_types' is evaluated, 'with_node_names' are
    evaluated as follows:

      For a profile data structure, profiler first finds the profiler
      nodes matching 'start_name_regexes', and starts displaying profiler
      nodes from there. Then, if a node matches 'show_name_regexes' and
      doesn't match 'hide_name_regexes', it's displayed. If a node matches
      'trim_name_regexes', profiler stops further searching that branch.

    Args:
      start_name_regexes: list of node name regexes to start displaying.
      show_name_regexes: list of node names regexes to display.
      hide_name_regexes: list of node_names regexes that should be hidden.
      trim_name_regexes: list of node name regexes from where to stop.
    Returns:
      self
    """
    if start_name_regexes is not None:
      self._options['start_name_regexes'] = copy.copy(start_name_regexes)
    if show_name_regexes is not None:
      self._options['show_name_regexes'] = copy.copy(show_name_regexes)
    if hide_name_regexes is not None:
      self._options['hide_name_regexes'] = copy.copy(hide_name_regexes)
    if trim_name_regexes is not None:
      self._options['trim_name_regexes'] = copy.copy(trim_name_regexes)
    return self

  def account_displayed_op_only(self, is_true):
    """Whether only account the statistics of displayed profiler nodes.

    Args:
      is_true: If true, only account statistics of nodes eventually
          displayed by the outputs.
          Otherwise, a node's statistics are accounted by its parents
          as long as it's types match 'account_type_regexes', even if
          it is hidden from the output, say, by hide_name_regexes.
    Returns:
      self
    """
    self._options['account_displayed_op_only'] = is_true
    return self

  def with_empty_output(self):
    """Do not generate side-effect outputs."""
    self._options['output'] = 'none'
    return self

  def with_stdout_output(self):
    """Print the result to stdout."""
    self._options['output'] = 'stdout'
    return self

  def with_file_output(self, outfile):
    """Print the result to a file."""
    self._options['output'] = 'file:outfile=%s' % outfile
    return self

  def with_timeline_output(self, timeline_file):
    """Generate a timeline json file."""
    self._options['output'] = 'timeline:outfile=%s' % timeline_file
    return self

  def with_pprof_output(self, pprof_file):
    """Generate a pprof profile gzip file.

    To use the pprof file:
      pprof -png --nodecount=100 --sample_index=1 <pprof_file>

    Args:
      pprof_file: filename for output, usually suffixed with .pb.gz.
    Returns:
      self.
    """
    self._options['output'] = 'pprof:outfile=%s' % pprof_file
    return self

  def order_by(self, attribute):
    # pylint: disable=line-too-long
    """Order the displayed profiler nodes based on a attribute.

    Supported attribute includes micros, bytes, occurrence, params, etc.
    https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/profiler/g3doc/options.md

    Args:
      attribute: An attribute the profiler node has.
    Returns:
      self
    """
    # pylint: enable=line-too-long
    self._options['order_by'] = attribute
    return self

  def select(self, attributes):
    # pylint: disable=line-too-long
    """Select the attributes to display.

    See https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/profiler/g3doc/options.md
    for supported attributes.

    Args:
      attributes: A list of attribute the profiler node has.
    Returns:
      self
    """
    # pylint: enable=line-too-long
    self._options['select'] = copy.copy(attributes)
    return self

  def with_step(self, step):
    """Which profile step to use for profiling.

    The 'step' here refers to the step defined by `Profiler.add_step()` API.

    Args:
      step: When multiple steps of profiles are available, select which step's
         profile to use. If -1, use average of all available steps.
    Returns:
      self
    """
    self._options['step'] = step
    return self


"""
Joint Label Fusion algorithm
"""

__all__ = ["joint_label_fusion", "local_joint_label_fusion"]

import os
import numpy as np
import warnings
from pathlib import Path
from tempfile import NamedTemporaryFile
from tempfile import mktemp
import glob
import re
import math

from .. import utils
from ..core import ants_image as iio
from ..core import ants_image_io as iio2
from .. import registration

def joint_label_fusion(
    target_image,
    target_image_mask,
    atlas_list,
    beta=4,
    rad=2,
    label_list=None,
    rho=0.01,
    usecor=False,
    r_search=3,
    nonnegative=False,
    no_zeroes=False,
    max_lab_plus_one=False,
    output_prefix=None,
    verbose=False,
):
    """
    A multiple atlas voting scheme to customize labels for a new subject.
    This function will also perform intensity fusion. It almost directly
    calls the C++ in the ANTs executable so is much faster than other
    variants in ANTsR.

    One may want to normalize image intensities for each input image before
    passing to this function. If no labels are passed, we do intensity fusion.
    Note on computation time: the underlying C++ is multithreaded.
    You can control the number of threads by setting the environment
    variable ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS e.g. to use all or some
    of your CPUs. This will improve performance substantially.
    For instance, on a macbook pro from 2015, 8 cores improves speed by about 4x.

    ANTsR function: `jointLabelFusion`

    Arguments
    ---------
    target_image : ANTsImage
        image to be approximated

    target_image_mask : ANTsImage
        mask with value 1

    atlas_list : list of ANTsImage types
        list containing intensity images

    beta : scalar
        weight sharpness, default to 2

    rad : scalar
        neighborhood radius, default to 2

    label_list : list of ANTsImage types (optional)
        list containing images with segmentation labels

    rho : scalar
        ridge penalty increases robustness to outliers but also makes image converge to average

    usecor : boolean
        employ correlation as local similarity

    r_search : scalar
        radius of search, default is 3

    nonnegative : boolean
        constrain weights to be non-negative

    no_zeroes : boolean
        this will constrain the solution only to voxels that are always non-zero in the label list

    max_lab_plus_one : boolean
        this will add max label plus one to the non-zero parts of each label where the target mask
        is greater than one.  NOTE: this will have a side effect of adding to the original label
        images that are passed to the program.  It also guarantees that every position in the
        labels have some label, rather than none.  Ie it guarantees to explicitly parcellate the
        input data.

    output_prefix: string
        file prefix for storing output probabilityimages to disk

    verbose : boolean
        whether to show status updates

    Returns
    -------
    dictionary w/ following key/value pairs:
        `segmentation` : ANTsImage
            segmentation image

        `intensity` : ANTsImage
            intensity image

        `probabilityimages` : list of ANTsImage types
            probability map image for each label

        `segmentation_numbers` : list of numbers
            segmentation label (number, int) for each probability map

    Example
    -------
    >>> import ants
    >>> ref = ants.image_read( ants.get_ants_data('r16'))
    >>> ref = ants.resample_image(ref, (50,50),1,0)
    >>> ref = ants.iMath(ref,'Normalize')
    >>> mi = ants.image_read( ants.get_ants_data('r27'))
    >>> mi2 = ants.image_read( ants.get_ants_data('r30'))
    >>> mi3 = ants.image_read( ants.get_ants_data('r62'))
    >>> mi4 = ants.image_read( ants.get_ants_data('r64'))
    >>> mi5 = ants.image_read( ants.get_ants_data('r85'))
    >>> refmask = ants.get_mask(ref)
    >>> refmask = ants.iMath(refmask,'ME',2) # just to speed things up
    >>> ilist = [mi,mi2,mi3,mi4,mi5]
    >>> seglist = [None]*len(ilist)
    >>> for i in range(len(ilist)):
    >>>     ilist[i] = ants.iMath(ilist[i],'Normalize')
    >>>     mytx = ants.registration(fixed=ref , moving=ilist[i] ,
    >>>         typeofTransform = ('Affine') )
    >>>     mywarpedimage = ants.apply_transforms(fixed=ref,moving=ilist[i],
    >>>             transformlist=mytx['fwdtransforms'])
    >>>     ilist[i] = mywarpedimage
    >>>     seg = ants.threshold_image(ilist[i],'Otsu', 3)
    >>>     seglist[i] = ( seg ) + ants.threshold_image( seg, 1, 3 ).morphology( operation='dilate', radius=3 )
    >>> r = 2
    >>> pp = ants.joint_label_fusion(ref, refmask, ilist, r_search=2,
    >>>                     label_list=seglist, rad=[r]*ref.dimension )
    >>> pp = ants.joint_label_fusion(ref,refmask,ilist, r_search=2, rad=[r]*ref.dimension)
    """
    segpixtype = "unsigned int"
    if (label_list is None) or (np.any([l is None for l in label_list])):
        doJif = True
    else:
        doJif = False

    if not doJif:
        if len(label_list) != len(atlas_list):
            raise ValueError("len(label_list) != len(atlas_list)")
        if no_zeroes:
            for label in label_list:
                target_image_mask[label == 0] = 0
        inlabs = set()
        for label in label_list:
            values = np.unique(label[target_image_mask != 0 and label != 0])
            inlabs = inlabs.union(values)
        inlabs = sorted(inlabs)
        maxLab = max(inlabs)
        if max_lab_plus_one:
            for label in label_list:
                label[label == 0] = maxLab + 1
        mymask = target_image_mask.clone()
    else:
        mymask = target_image_mask

###### security issues with mktemp but could not figure out the right solution
###### NamedTemporaryFile creates a file with permissions:
###### -rw-------  1 stnava  staff
###### whereas mktemp gives
###### -rw-r--r--  1 stnava  staff
###### the latter is what we want - one solution is to use chmod via os but
###### am currently too lazy to change one line of code to two or more everywhere

#    osegfn = NamedTemporaryFile(prefix="antsr", suffix="myseg.nii.gz",delete=False).name
    osegfn = mktemp(prefix="antsr", suffix="myseg.nii.gz")
    # segdir = osegfn.replace(os.path.basename(osegfn),'')

    if os.path.exists(osegfn):
        os.remove(osegfn)

    if output_prefix is None:
#        probs = NamedTemporaryFile(prefix="antsr", suffix="prob%02d.nii.gz",delete=False).name
        probs = mktemp(prefix="antsr", suffix="prob%02d.nii.gz")
        probsbase = os.path.basename(probs)
        tdir = probs.replace(probsbase, "")
        searchpattern = probsbase.replace("%02d", "*")

    if output_prefix is not None:
        probs = output_prefix + "prob%02d.nii.gz"
        probpath = Path(probs).parent
        Path(probpath).mkdir(parents=True, exist_ok=True)
        probsbase = os.path.basename(probs)
        tdir = probs.replace(probsbase, "")
        searchpattern = probsbase.replace("%02d", "*")

    mydim = target_image_mask.dimension
    if not doJif:
        # not sure if these should be allocated or what their size should be
        outimg = label_list[1].clone(segpixtype)
        outimgi = target_image * 0

        outimg_ptr = utils.get_pointer_string(outimg)
        outimgi_ptr = utils.get_pointer_string(outimgi)
        outs = "[%s,%s,%s]" % (outimg_ptr, outimgi_ptr, probs)
    else:
        outimgi = target_image * 0
        outs = utils.get_pointer_string(outimgi)

    mymask = mymask.clone(segpixtype)
    if (not isinstance(rad, (tuple, list))) or (len(rad) == 1):
        myrad = [rad] * mydim
    else:
        myrad = rad

    if len(myrad) != mydim:
        raise ValueError("path radius dimensionality must equal image dimensionality")

    myrad = "x".join([str(mr) for mr in myrad])
    vnum = 1 if verbose else 0
    nnum = 1 if nonnegative else 0
    mypc = "MSQ"
    if usecor:
        mypc = "PC"

    myargs = {
        "d": mydim,
        "t": target_image,
        "a": rho,
        "b": beta,
        "c": nnum,
        "p": myrad,
        "m": mypc,
        "s": r_search,
        "x": mymask,
        "o": outs,
        "v": vnum,
    }

    kct = len(myargs.keys())
    for k in range(len(atlas_list)):
        kct += 1
        myargs["g-MULTINAME-%i" % kct] = atlas_list[k]
        if not doJif:
            kct += 1
            castseg = label_list[k].clone(segpixtype)
            myargs["l-MULTINAME-%i" % kct] = castseg

    myprocessedargs = utils._int_antsProcessArguments(myargs)

    libfn = utils.get_lib_fn("antsJointFusion")
    rval = libfn(myprocessedargs)
    if rval != 0:
        print("Warning: Non-zero return from antsJointFusion")

    if doJif:
        return outimgi

    probsout = glob.glob(os.path.join(tdir, "*" + searchpattern))
    probsout.sort()
    probimgs = []
#    print( os.system("ls -l "+probsout[0]) )
    for idx in range(len(probsout)):
        probimgs.append(iio2.image_read(probsout[idx]))

    #    if len(probsout) != (len(inlabs)) and max_lab_plus_one == False:
    #        warnings.warn("Length of output probabilities != length of unique input labels")

    segmentation_numbers = [0] * len(probsout)
    for i in range(len(probsout)):
        temp = str.split(probsout[i], "prob")
        segnum = temp[len(temp) - 1].split(".nii.gz")[0]
        segmentation_numbers[i] = int(segnum)

    if max_lab_plus_one == False:
        segmat = iio2.images_to_matrix(probimgs, target_image_mask)
        finalsegvec = segmat.argmax(axis=0)
        finalsegvec2 = finalsegvec.copy()
        # mapfinalsegvec to original labels
        for i in range(len(probsout)):
            temp = str.split(probsout[i], "prob")
            segnum = temp[len(temp) - 1].split(".nii.gz")[0]
            finalsegvec2[finalsegvec == i] = segnum
        outimg = iio2.make_image(target_image_mask, finalsegvec2)

        return {
            "segmentation": outimg,
            "intensity": outimgi,
            "probabilityimages": probimgs,
            "segmentation_numbers": segmentation_numbers,
        }

    if max_lab_plus_one == True:
        mymaxlab = max(segmentation_numbers)
        matchings_indices = [
            i
            for i, segmentation_numbers in enumerate(segmentation_numbers)
            if segmentation_numbers == mymaxlab
        ]
        background_prob = probimgs[matchings_indices[0]]
        background_probfn = probsout[matchings_indices[0]]
        del probimgs[matchings_indices[0]]
        del probsout[matchings_indices[0]]
        del segmentation_numbers[matchings_indices[0]]

        segmat = iio2.images_to_matrix(probimgs, target_image_mask)

        finalsegvec = segmat.argmax(axis=0)
        finalsegvec2 = finalsegvec.copy()
        # mapfinalsegvec to original labels
        for i in range(len(probsout)):
            temp = str.split(probsout[i], "prob")
            segnum = temp[len(temp) - 1].split(".nii.gz")[0]
            finalsegvec2[finalsegvec == i] = segnum

        outimg = iio2.make_image(target_image_mask, finalsegvec2)

        # next decide what is "background" based on the sum of the first k labels vs the prob of the last one
        firstK = probimgs[0] * 0
        for i in range(len(probsout)):
            firstK = firstK + probimgs[i]

        segmat = iio2.images_to_matrix([background_prob, firstK], target_image_mask)
        bkgsegvec = segmat.argmax(axis=0)
        outimg = outimg * iio2.make_image(target_image_mask, bkgsegvec)

        return {
            "segmentation": outimg * iio2.make_image(target_image_mask, bkgsegvec),
            "segmentation_raw": outimg,
            "intensity": outimgi,
            "probabilityimages": probimgs,
            "segmentation_numbers": segmentation_numbers,
            "background_prob": background_prob,
        }

def local_joint_label_fusion(
    target_image,
    which_labels,
    target_mask,
    initial_label,
    atlas_list,
    label_list,
    submask_dilation=10,
    type_of_transform="SyN",
    aff_metric="meansquares",
    syn_metric="mattes",
    syn_sampling=32,
    reg_iterations=(40, 20, 0),
    aff_iterations=(500, 50, 0),
    grad_step=0.2,
    flow_sigma=3,
    total_sigma=0,
    beta=4,
    rad=2,
    rho=0.1,
    usecor=False,
    r_search=3,
    nonnegative=False,
    no_zeroes=False,
    max_lab_plus_one=False,
    local_mask_transform="Similarity",
    output_prefix=None,
    verbose=False,
):
    """
    A local version of joint label fusion that focuses on a subset of labels.
    This is primarily different from standard JLF because it performs
    registration on the label subset and focuses JLF on those labels alone.

    ANTsR function: `localJointLabelFusion`

    Arguments
    ---------
    target_image : ANTsImage
        image to be labeled

    which_labels : numeric vector
        label number(s) that exist(s) in both the template and library

    target_image_mask : ANTsImage
        a mask for the target image (optional), passed to joint fusion

    initial_label : ANTsImage
        initial label set, may be same labels as library or binary.
        typically labels would be produced by a single deformable registration
        or by manual labeling.

    atlas_list : list of ANTsImage types
        list containing intensity images

    label_list : list of ANTsImage types (optional)
        list containing images with segmentation labels

    submask_dilation : integer
        amount to dilate initial mask to define region on which
        we perform focused registration

    type_of_transform : string
        A linear or non-linear registration type. Mutual information metric by default.
        See Notes below for more.

    aff_metric : string
        the metric for the affine part (GC, mattes, meansquares)

    syn_metric : string
        the metric for the syn part (CC, mattes, meansquares, demons)

    syn_sampling : scalar
        the nbins or radius parameter for the syn metric

    reg_iterations : list/tuple of integers
        vector of iterations for syn. we will set the smoothing and multi-resolution parameters based on the length of this vector.

    aff_iterations : list/tuple of integers
        vector of iterations for low-dimensional registration.

    grad_step : scalar
        gradient step size (not for all tx)

    flow_sigma : scalar
        smoothing for update field

    total_sigma : scalar
        smoothing for total field

    beta : scalar
        weight sharpness, default to 2

    rad : scalar
        neighborhood radius, default to 2

    rho : scalar
        ridge penalty increases robustness to outliers but also makes image converge to average

    usecor : boolean
        employ correlation as local similarity

    r_search : scalar
        radius of search, default is 3

    nonnegative : boolean
        constrain weights to be non-negative

    no_zeroes : boolean
        this will constrain the solution only to voxels that are always non-zero in the label list

    max_lab_plus_one : boolean
        this will add max label plus one to the non-zero parts of each label where the target mask
        is greater than one.  NOTE: this will have a side effect of adding to the original label
        images that are passed to the program.  It also guarantees that every position in the
        labels have some label, rather than none.  Ie it guarantees to explicitly parcellate the
        input data.

    local_mask_transform: string
        the type of transform for the local mask alignment - usually translation,
        rigid, similarity or affine.

    output_prefix: string
        file prefix for storing output probabilityimages to disk

    verbose : boolean
        whether to show status updates

    Returns
    -------
    dictionary w/ following key/value pairs:
        `segmentation` : ANTsImage
            segmentation image

        `intensity` : ANTsImage
            intensity image

        `probabilityimages` : list of ANTsImage types
            probability map image for each label

    """
    myregion = utils.mask_image(initial_label, initial_label, which_labels)
    if myregion.max() == 0:
        myregion = utils.threshold_image(initial_label, 1, math.inf)

    myregionb = utils.threshold_image(myregion, 1, math.inf)
    myregionAroundRegion = utils.iMath(myregionb, "MD", submask_dilation)
    if target_mask is not None:
        myregionAroundRegion = myregionAroundRegion * target_mask
    croppedImage = utils.crop_image(target_image, myregionAroundRegion)
    croppedMask = utils.crop_image(myregionAroundRegion, myregionAroundRegion)
    mycroppedregion = utils.crop_image(myregion, myregionAroundRegion)
    croppedmappedImages = []
    croppedmappedSegs = []
    if verbose is True:
        print("Begin registrations:")
    for k in range(len(atlas_list)):

        if verbose is True:
            print(str(k) + "...")

        if verbose is True:
            print( "local-seg-tx: " + local_mask_transform )
        libregion = utils.mask_image(label_list[k], label_list[k], which_labels)
        initMap = registration.registration(
            mycroppedregion, libregion, type_of_transform=local_mask_transform, aff_metric=aff_metric, aff_iterations=aff_iterations, verbose=False
        )["fwdtransforms"]
        if verbose is True:
            print( "local-img-tx: " + type_of_transform )
        localReg = registration.registration(
            croppedImage,
            atlas_list[k],
            reg_iterations=reg_iterations,
            flow_sigma=flow_sigma,
            total_sigma=total_sigma,
            grad_step=grad_step,
            type_of_transform=type_of_transform,
            syn_metric=syn_metric,
            syn_sampling=syn_sampling,
            initial_transform=initMap[0],
            verbose=False,
        )
        transformedImage = registration.apply_transforms(
            croppedImage, atlas_list[k], localReg["fwdtransforms"]
        )
        transformedLabels = registration.apply_transforms(
            croppedImage,
            label_list[k],
            localReg["fwdtransforms"],
            interpolator="nearestNeighbor",
        )
        croppedmappedImages.append(transformedImage)
        croppedmappedSegs.append(transformedLabels)

    ljlf = joint_label_fusion(
        croppedImage,
        croppedMask,
        atlas_list=croppedmappedImages,
        label_list=croppedmappedSegs,
        beta=beta,
        rad=rad,
        rho=rho,
        usecor=usecor,
        r_search=r_search,
        nonnegative=nonnegative,
        no_zeroes=no_zeroes,
        max_lab_plus_one=max_lab_plus_one,
        output_prefix=output_prefix,
        verbose=verbose,
    )

    return {
        "ljlf": ljlf,
        "croppedImage": croppedImage,
        "croppedmappedImages": croppedmappedImages,
        "croppedmappedSegs": croppedmappedSegs,
    }


from collections import Counter, defaultdict, deque
from functools import reduce, lru_cache
from itertools import permutations
from typing import (
    List,
    Tuple,
    Set,
    Dict,
    Iterable,
    DefaultDict,
    Optional,
    Union,
    Generator,
)
from copy import deepcopy
import re
from heapq import heappop, heappush
from time import sleep

from intcode import IntCode
from termcolor import colored

def parse(filename: str) -> IntCode:
    matrix = []
    with open(filename, "r") as f:
        lines = f.read().strip().replace("\n", "")

    l = [int(x) for x in lines.split(",")]

    d = {i: l[i] for i in range(len(l))}
    return IntCode(d)

def str_to_cmd(string):
    cmd = [ord(i) for i in string]
    return cmd

def print_out(intcode):
    outs = [chr(char) for char in intcode.outs]
    for grid in "".join(outs).split("\n\n"):
        print(grid)
        from time import sleep
        sleep(0.3)
    # NOT B T
    # OR T J
    # NOT C T
    # OR J T
    # NOT D J
    # OR T J
    # WALK

def run_program(intcode):
    # cmd = "NOT A J\nNOT B J\nNOT C J\nNOT D J\nWALK\n"
    instr = """NOT C T
    NOT D J
    NOT J J
    AND T J
    NOT A T
    OR T J
    WALK
    """
    cmd = instr
    intcode.inputs.extend(str_to_cmd(cmd))
    intcode.run()
    try:
        print_out(intcode)
    except ValueError:
        return intcode.outs[-1]

def run_program_p2(intcode):
    instr = """NOT C J
    AND D J
    AND H J
    NOT B T
    AND D T
    OR T J
    NOT A T
    OR T J
    RUN
    """
    cmd = instr
    intcode.inputs.extend(str_to_cmd(cmd))
    intcode.run()
    try:
        print_out(intcode)
    except ValueError:
        return intcode.outs[-1]

def main(filename: str) -> Tuple[Optional[int], Optional[int]]:
    from time import time

    start = time()
    answer_a, answer_b = None, None
    intcode = parse(filename)
    answer_a = run_program(intcode)
    print(f"p1: {answer_a}")
    # p2
    intcode = parse(filename)
    answer_b = run_program_p2(intcode)
    print(f"p2: {answer_b}")
    end = time()
    print(end - start)
    return answer_a, answer_b

if __name__ == "__main__":
    from utils import submit_answer
    from aocd.exceptions import AocdError

    sample = "sample.txt"
    inp = "input.txt"

    # sample_a_answer = 1125899906842624
    # sample_b_answer = 18216

    # answer_a, answer_b = main(sample)
    # assert (
    #     answer_a == sample_a_answer
    # ), f"AnswerA incorrect: Actual: {answer_a}, Expected: {sample_a_answer}"
    # print("sampleA correct")
    # if answer_b:
    #     assert (
    #         answer_b == sample_b_answer
    #     ), f"AnswerB incorrect: Actual: {answer_b}, Expected: {sample_b_answer}"
    #     print("sampleB correct")

    # Test on your input and submit
    answer_a, answer_b = main(inp)
    print(f"Your input answers: \nA: {answer_a}\nB: {answer_b}")
    # try:
    #     submit_answer(answer_a, "a", day=15, year=2019)
    # except AocdError:
    #     submit_answer(answer_b, "b", day=15, year=2019)


from core.contracts import GetMyPlacesRequest, AddPlaceRequest, RemovePlaceRequest, PlaceType

from core.storage import Storage

class MyPlacesStore:
    def __init__(self, storage: Storage):
        self._store = storage

    def my_places_ids(self, request: GetMyPlacesRequest):
        key = self._get_key(request.type)
        data = self._store.load(key)
        return list(data) if data is not None else []

    def add_my_place(self, request: AddPlaceRequest):
        key = self._get_key(request.type)
        place_list = self._store.load(key)
        if not place_list:
            place_list = set()

        place_list.add(request.id)
        self._store.save(key, place_list)

    def remove_my_place(self, request: RemovePlaceRequest):
        key = self._get_key(request.type)
        place_list = self._store.load(key)
        if not place_list or request.id not in place_list:
            return

        place_list.remove(request.id)
        self._store.save(key, place_list)

    @staticmethod
    def _get_key(place_type: PlaceType):
        return 'myplaces' + place_type.name


from collections import defaultdict, deque
from itertools import permutations
from sys import stdin,stdout
from bisect import bisect_left, bisect_right
from copy import deepcopy
#from random import randint

int_input=lambda : int(stdin.readline())
string_input=lambda : stdin.readline()
multi_int_input =lambda : map(int, stdin.readline().split())
multi_input = lambda : stdin.readline().split()
list_input=lambda : list(map(int,stdin.readline().split()))
string_list_input=lambda: list(string_input())
MOD = pow(10,9)+7

test = int_input()

for _ in range(test):
    x,y = multi_int_input()

    if x>y:
        print("YES")
    elif x==y:
        print("YES")
    elif x<y:
        if x == 2 and y == 3:
            print("YES")
        elif x>=4:
            print("YES")
        else:
            print("NO")


from typing import Optional, Dict, List
from dijkstra import Dijkstra
from weighted_graph import WeightedGraph
from weighted_edge import WeightedEdge
import sys

WeightedPath = List[WeightedEdge]  # type alias for paths

def default_data():
    city_graph2: WeightedGraph[str] = WeightedGraph(
        ["Seattle", "San Francisco", "Los Angeles", "Riverside", "Phoenix", "Chicago", "Boston", "New York", "Atlanta",
         "Miami", "Dallas", "Houston", "Detroit", "Philadelphia", "Washington"])
    city_graph2.add_edge_by_vertices("Seattle", "Chicago", 1737)
    city_graph2.add_edge_by_vertices("Seattle", "San Francisco", 678)
    city_graph2.add_edge_by_vertices("San Francisco", "Riverside", 386)
    city_graph2.add_edge_by_vertices("San Francisco", "Los Angeles", 348)
    city_graph2.add_edge_by_vertices("Los Angeles", "Riverside", 50)
    city_graph2.add_edge_by_vertices("Los Angeles", "Phoenix", 357)
    city_graph2.add_edge_by_vertices("Riverside", "Phoenix", 307)
    city_graph2.add_edge_by_vertices("Riverside", "Chicago", 1704)
    city_graph2.add_edge_by_vertices("Phoenix", "Dallas", 887)
    city_graph2.add_edge_by_vertices("Phoenix", "Houston", 1015)
    city_graph2.add_edge_by_vertices("Dallas", "Chicago", 805)
    city_graph2.add_edge_by_vertices("Dallas", "Atlanta", 721)
    city_graph2.add_edge_by_vertices("Dallas", "Houston", 225)
    city_graph2.add_edge_by_vertices("Houston", "Atlanta", 702)
    city_graph2.add_edge_by_vertices("Houston", "Miami", 968)
    city_graph2.add_edge_by_vertices("Atlanta", "Chicago", 588)
    city_graph2.add_edge_by_vertices("Atlanta", "Washington", 543)
    city_graph2.add_edge_by_vertices("Atlanta", "Miami", 604)
    city_graph2.add_edge_by_vertices("Miami", "Washington", 923)
    city_graph2.add_edge_by_vertices("Chicago", "Detroit", 238)
    city_graph2.add_edge_by_vertices("Detroit", "Boston", 613)
    city_graph2.add_edge_by_vertices("Detroit", "Washington", 396)
    city_graph2.add_edge_by_vertices("Detroit", "New York", 482)
    city_graph2.add_edge_by_vertices("Boston", "New York", 190)
    city_graph2.add_edge_by_vertices("New York", "Philadelphia", 81)
    city_graph2.add_edge_by_vertices("Philadelphia", "Washington", 123)

    _Path = Dijkstra()
    distances, path_dict = _Path.execute_alg(city_graph2, "Los Angeles")
    name_distance: Dict[str, Optional[int]] = _Path.distance_array_to_vertex_dict(city_graph2, distances)
    print("Расстояние от Los Angeles:")
    for key, value in name_distance.items():
        print(f"{key} : {value}")
    print("")  # blank line

    print("Кратчайшее расстояние от Los Angeles до Boston:")
    path: WeightedPath = _Path.path_dict_to_path(city_graph2.index_of("Los Angeles"), city_graph2.index_of("Boston"),
                                                 path_dict)
    _Path.print_weighted_path(city_graph2, path)

def create_graph() -> WeightedGraph:
    result: list = []
    input_city: str = ''
    while input_city != 'exit':
        print("Введите название вершины: ")
        input_city = input()
        if input_city == 'exit':
            break
        result.append(input_city)
    city_graph: WeightedGraph[str] = WeightedGraph(result)
    return city_graph

def create_edge(graph: WeightedGraph) -> None:
    a: str
    b: str
    weight: float
    print("Введите название вершины 1: ")
    a = input()
    print("Введите название вершины 2: ")
    b = input()
    print("Введите вес ребра: ")
    weight = float(input())
    graph.add_edge_by_vertices(a, b, weight)

def start_dijkstra():
    graph: WeightedGraph = create_graph()
    input_edge: str = ''
    while input_edge != 'exit':
        print("Для выхода напишите exit")
        input_edge = input()
        if input_edge == 'exit': break
        create_edge(graph)
    _Path = Dijkstra()
    print("Введите вершину из которой строить маршруты: ")
    start_point: str = input()
    distances, path_dict = _Path.execute_alg(graph, start_point)
    name_distance: Dict[str, Optional[int]] = _Path.distance_array_to_vertex_dict(graph, distances)
    print(f"Расстояние от {start_point}:")
    for key, value in name_distance.items():
        print(f"{key} : {value}")
    print("")  # blank line
    print("Введите вершину куда строить маршрут: ")
    end_point: str = input()
    print(f"Кратчайшее расстояние от {start_point} до {end_point}:")
    path: WeightedPath = _Path.path_dict_to_path(graph.index_of(start_point), graph.index_of(end_point),
                                                 path_dict)
    _Path.print_weighted_path(graph, path)

if __name__ == "__main__":
    command_line: str = ""
    while command_line != 'exit':
        print("Введите комманду (default): \n 1. create для создания своего графа \n "
              "2. default для использования данных по умолчанию"
              "\n 3. exit для выхода"
              "\n $> ")
        command_line = input()
        if command_line == "default":
            default_data()
        elif command_line == "create":
            start_dijkstra()
        elif command_line == "exit":
            try:
                sys.exit()
            except:
                print("Работы программы завершена")


import sys
read = sys.stdin.readline

def read_ints():
    return list(map(int, read().split()))

def read_a_int():
    return int(read())

def read_matrix(H):
    '''
    H is number of rows
    '''
    return [list(map(int, read().split())) for _ in range(H)]

def read_map(H):
    '''
    H is number of rows
    文字列で与えられた盤面を読み取る用
    '''
    return [read()[:-1] for _ in range(H)]

def read_col(H, n_cols):
    '''
    H is number of rows
    n_cols is number of cols

    A列、B列が与えられるようなとき
    '''
    ret = [[] for _ in range(n_cols)]
    for _ in range(H):
        tmp = list(map(int, read().split()))
        for col in range(n_cols):
            ret[col].append(tmp[col])

    return ret

# このグラフ構造の中で一番遠い連結成分では？
H, W = read_ints()

from collections import deque, defaultdict
from itertools import product
Tree = defaultdict(lambda: [])

# input data
S = read_map(H)
node = -1
for i, j in product(range(H), range(W)):
    node += 1
    if S[i][j] == '#':
        continue
    for ni, nj in zip([0, 1, 0, -1], [1, 0, -1, 0]):
        if -1 < i + ni < H and -1 < j + nj < W and S[i + ni][j + nj] == '.':
            Tree[node].append((node + (W * ni + nj), 1))
            Tree[node + (W * ni + nj)].append((node, 1))

def bfs(Tree, n_V, s):
    '''
    指定した点sからの単一始点で各点までの距離を返す。
    n_Vは頂点の数
    Treeはdefault dictで、valueには(隣接ノード,そこまでのコスト)がリスト形式で格納されているとする。
    '''
    INF = -10**9
    Dists = [INF] * n_V  # 距離の初期化 #こいつを更新して返すことにする
    is_visited = [False] * n_V
    is_visited[s] = True
    que = deque([(s, 0)])  # (ノード番号,そこまでたどり着くためのコスト)
    while que:
        cur, cost = que.popleft()
        Dists[cur] = cost
        for nx_node, nx_cost in Tree[cur]:
            if is_visited[nx_node]:
                continue
            que.append((nx_node, nx_cost + cost))
            is_visited[nx_node] = True

    return Dists

# 任意の点から一番遠い点を求めて、そこからさらに一番遠い点がほしい
for i, j in product(range(H), range(W)):
    if S[i][j] == '.':
        Dists = bfs(Tree, W * H, i * W + j)
        break

next_node = Dists.index(max(Dists))  # numpyでいうargmaxしてる
Dists = bfs(Tree, W * H, next_node)

print(max(Dists))


from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier

def get_model(model_name):
    models = {
    "KNN":KNeighborsClassifier,
    "SVM":SVC,
    "Random Forest":RandomForestClassifier
    }

    return models.get(model_name)


from collections import deque

t = int(input())

for tc in range(t):
    v, e = map(int, input().split())

    vertex = [0] * (v + 1)
    graph = [[] for _ in range(v + 1)]

    for i in range(e):
        x, y = map(int, input().split())
        graph[x].append(y)
        graph[y].append(x)

    queue = deque()
    group = 1
    result = True
    for i in range(1, v+1):
        if vertex[i] == 0:
            queue.append(i)
            vertex[i] = group
            while queue:
                a = queue.popleft()
                for temp in graph[a]:
                    if vertex[temp] == 0:
                        queue.append(temp)
                        vertex[temp] = -vertex[a]
                    elif vertex[temp] == vertex[a]:
                        result = False
                        break
                if not result:
                    break
        if not result:
            break

    if result:
        print("YES")
    else:
        print("NO")


import telebot
from telebot import types, TeleBot

bot: TeleBot = telebot.TeleBot('6153432051:AAFZrE-r4My1jiYLbRpGPMcf7QoVVsY1Mk0')

@bot.message_handler(commands=['start'])
def start_message(message):
    name = f'Привет, {message.from_user.first_name}'
    bot.send_message(message.chat.id, name, parse_mode='html')
    bot.send_message(message.chat.id, 'Привет меня зовут Подручный, я помогу тебе подготовться к ЕГЭ по русскому языку', parse_mode='html')
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=3)
    st = types.KeyboardButton('Структура')
    ex = types.KeyboardButton('Теория')
    markup.add(st, ex)
    bot.send_message(message.chat.id, "Тебя интерисует структура или теория к каждому заданию?", reply_markup=markup)

@bot.message_handler(content_types=['text'])
def get_user_text(message):
    if message.text == 'Структура':
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=3)
        k = types.KeyboardButton('Кодификатор')
        s = types.KeyboardButton('Спецификация')
        d = types.KeyboardButton('Демоверсия')
        markup.add(k, s, d)
        bot.send_message(message.chat.id, "Кодификатор, спецификация или демоверсия",
                         reply_markup=markup)
    elif message.text == 'Кодификатор':
        ko = open('kodif.pdf', 'rb')
        bot.send_document(message.chat.id, ko)
        menu(message)
    elif message.text == 'Спецификация':
        sp = open('spez.pdf', 'rb')
        bot.send_document(message.chat.id, sp)
        menu(message)
    elif message.text == 'Демоверсия':
        de = open('demo.pdf', 'rb')
        bot.send_document(message.chat.id, de)
        menu(message)
    elif message.text == 'Теория':
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=2)
        z = types.KeyboardButton('Теория к каждому заданию')
        slo = types.KeyboardButton('Словари')
        soch = types.KeyboardButton('Сочинение')
        ot= types.KeyboardButton('Отработка заданий')
        markup.add(z, slo, soch, ot)
        bot.send_message(message.chat.id, "Теория к каждому заданию, словари, сочинение, отработка заданий",
                         reply_markup=markup)

    elif message.text == 'Словари':
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=2)
        sl = types.KeyboardButton('Орфографический')
        par = types.KeyboardButton('Паронимы')
        markup.add(sl, par)
        bot.send_message(message.chat.id, "Орфографический или паронимы",
                         reply_markup=markup)
    elif message.text == 'Орфографический':
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=5)
        ab = types.KeyboardButton('А-Б')
        vi = types.KeyboardButton('В-И')
        ko = types.KeyboardButton('К-О')
        ps = types.KeyboardButton('П-С')
        tu = types.KeyboardButton('Т-Ю')
        markup.add(ab,vi, ko, ps, tu)
        bot.send_message(message.chat.id, 'Выбери на какие буквы', reply_markup=markup)
    elif message.text == 'А-Б':
        abb=open('Desktop - 1а-б.jpg', 'rb')
        bot.send_photo(message.chat.id, abb)
        orfo(message)
    elif message.text == 'В-И':
        vii=open('Desktop - 1в-и.jpg', 'rb')
        bot.send_photo(message.chat.id, vii)
        orfo(message)
    elif message.text == 'К-О':
        koo=open('Desktop - 1к-о.jpg', 'rb')
        bot.send_photo(message.chat.id, koo)
        orfo(message)
    elif message.text == 'П-С':
        pss=open('Desktop - 1п-с.jpg', 'rb')
        bot.send_photo(message.chat.id, pss)
        orfo(message)
    elif message.text == 'Т-Ю':
        tuu=open('Frame 1т-ю.jpg', 'rb')
        bot.send_photo(message.chat.id, tuu)
        orfo(message)
    elif message.text == 'Паронимы':
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=6)
        av = types.KeyboardButton('А-В')
        gj = types.KeyboardButton('Г-Ж')
        zl = types.KeyboardButton('З-Л')
        mo = types.KeyboardButton('М-О')
        pr = types.KeyboardButton('П-Р')
        si = types.KeyboardButton('С-Я')
        markup.add(av, gj, zl,mo, pr, si )
        bot.send_message(message.chat.id, 'На какие буквы', reply_markup=markup)
    elif message.text == 'А-В':
        avv=open('Desktop - 1а-в.jpg', 'rb')
        bot.send_photo(message.chat.id, avv)
        paronim(message)
    elif message.text == 'Г-Ж':
        gg=open('Desktop - 1г-ж.jpg', 'rb')
        bot.send_photo(message.chat.id, gg)
        paronim(message)
    elif message.text == 'З-Л':
        zz=open('Desktop - 1з-л.jpg', 'rb')
        bot.send_photo(message.chat.id, zz)
        paronim(message)
    elif message.text == 'М-О':
        mm=open('Desktop - 1м-о.jpg', 'rb')
        bot.send_photo(message.chat.id, mm)
        paronim(message)
    elif message.text == 'П-Р':
        pp=open('Desktop - 1п-р.jpg', 'rb')
        bot.send_photo(message.chat.id, pp)
        paronim(message)
    elif message.text == 'С-Я':
        ss=open('Desktop - 1с-я.jpg', 'rb')
        bot.send_photo(message.chat.id, ss)
        paronim(message)
    elif message.text == 'Сочинение':
        so = open('Desktop - 11-3.jpg', 'rb')
        so2 = open('Desktop - 14-7.jpg', 'rb')
        bot.send_photo(message.chat.id, so)
        bot.send_photo(message.chat.id, so2)
        menu(message)
    elif message.text == 'Теория к каждому заданию':
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=5)
        one = types.KeyboardButton('1')
        thr = types.KeyboardButton('3')
        fr = types.KeyboardButton('4')
        fv = types.KeyboardButton('5')
        sx = types.KeyboardButton('6')
        sw = types.KeyboardButton('7')
        ei = types.KeyboardButton('8')
        nn = types.KeyboardButton('9')
        tn = types.KeyboardButton('10')
        one1 = types.KeyboardButton('11')
        tw1 = types.KeyboardButton('12')
        thr1 = types.KeyboardButton('13')
        fr1 = types.KeyboardButton('14')
        fv1 = types.KeyboardButton('15')
        sx1 = types.KeyboardButton('16')
        sw1 = types.KeyboardButton('17')
        ei1 = types.KeyboardButton('18')
        nn1 = types.KeyboardButton('19')
        tn1 = types.KeyboardButton('20')
        one2 = types.KeyboardButton('21')
        sx2 = types.KeyboardButton('26')
        markup.add(one, thr, fr, fv, sx, sw, ei, nn, tn, one1, tw1, thr1, fr1, fv1, sx1, sw1, ei1, nn1, tn1, one2, sx2)
        bot.send_message(message.chat.id, 'Выбери задание', reply_markup=markup)
    elif message.text == '1':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Frame 11.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 11.1.jpg', 'rb')), ])
        bot.send_message(message.chat.id, 'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=354')
        teor(message)

    elif message.text == '3':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 13.1.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Frame 13.2.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Frame 23.3.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Frame 33.4.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Frame 43.5.jpg', 'rb')), ])
        bot.send_message(message.chat.id, 'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=356')
        teor(message)
    elif message.text == '4':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 14.1.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 24.2.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 34.3.jpg', 'rb')),])
        bot.send_message(message.chat.id, 'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=340')
        teor(message)
    elif message.text == "5":
        markup = types.InlineKeyboardMarkup()
        markup.add(types.InlineKeyboardButton("Отработка задания",
                                              url="https://rus-ege.sdamgia.ru/"))
        bot.send_message(message.chat.id, "Отработкаа задания", reply_markup=markup)
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=5)
        par = types.KeyboardButton('Паронимы')
        st = types.KeyboardButton('Структура')
        ex = types.KeyboardButton('Теория')
        z = types.KeyboardButton('Теория к каждому заданию')
        markup.add(st, ex, z, par)
        bot.send_message(message.chat.id, "Паронимы словарь" , reply_markup=markup)

    elif message.text == '6':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 16.1.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 26.2.jpg', 'rb')), ])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=353')
        teor(message)
    elif message.text == '7':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 17.1.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 27.2.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 47.3.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 57.4.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 67.5.png', 'rb')), ])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=287')
        teor(message)
    elif message.text == '8':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 18.1.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 28.2.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 38.3.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 48.4.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 58.5.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 68.6.jpg', 'rb')),])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=333')
        teor(message)
    elif message.text == '9':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 29.1.jpg', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 39.2.jpg', 'rb')), ])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=358')
        teor(message)
    elif message.text == '10':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 110.1.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 210.2.png', 'rb')), ])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=348')
        teor(message)
    elif message.text == '11':
        abb = open('Desktop - 111.jpg', 'rb')
        bot.send_photo(message.chat.id, abb)
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=351')
        teor(message)
    elif message.text == '12':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 112.1.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 212.2.png', 'rb')), ])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=350')
        teor(message)
    elif message.text == '13':
        abb = open('Desktop - 113.png', 'rb')
        bot.send_photo(message.chat.id, abb)
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=272')
        teor(message)
    elif message.text == '14':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 114.1.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 214.2.png', 'rb')), ])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=273')
        teor(message)
    elif message.text == '15':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 115.1.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 215.2.png', 'rb')), ])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=267')
        teor(message)
    elif message.text == '16':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 116.1.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 216.2.png', 'rb')), ])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=277')
        teor(message)
    elif message.text == '17':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 117.3.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 217.2.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 317.3.png', 'rb')),])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=275')
        teor(message)
    elif message.text == '18':
        abb = open('Desktop - 118.png', 'rb')
        bot.send_photo(message.chat.id, abb)
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=306')
        teor(message)
    elif message.text == '19':
        abb = open('Desktop - 119.png', 'rb')
        bot.send_photo(message.chat.id, abb)
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=309')
        teor(message)
    elif message.text == '20':
        abb = open('Desktop - 120.png', 'rb')
        bot.send_photo(message.chat.id, abb)
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=280')
        teor(message)
    elif message.text == '21':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 121.1.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 221.2.png', 'rb')),])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=364')
        teor(message)

    elif message.text == '26':
        bot.send_media_group(message.chat.id, [telebot.types.InputMediaPhoto(open('Desktop - 126.1.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 226.2.png', 'rb')),
                                               telebot.types.InputMediaPhoto(open('Desktop - 326.3.png', 'rb')),])
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=275')
        teor(message)
    elif message.text == 'Отработка заданий':
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=5)
        one = types.KeyboardButton('1о')
        tw = types.KeyboardButton('2о')
        thr = types.KeyboardButton('3о')
        fr = types.KeyboardButton('4о')
        fv = types.KeyboardButton('5о')
        sx = types.KeyboardButton('6о')
        sw = types.KeyboardButton('7о')
        ei = types.KeyboardButton('8о')
        nn = types.KeyboardButton('9о')
        tn = types.KeyboardButton('10о')
        one1 = types.KeyboardButton('11о')
        tw1 = types.KeyboardButton('12о')
        thr1 = types.KeyboardButton('13о')
        fr1 = types.KeyboardButton('14о')
        fv1 = types.KeyboardButton('15о')
        sx1 = types.KeyboardButton('16о')
        sw1 = types.KeyboardButton('17о')
        ei1 = types.KeyboardButton('18о')
        nn1 = types.KeyboardButton('19о')
        tn1 = types.KeyboardButton('20о')
        one2 = types.KeyboardButton('21о')
        ei3 = types.KeyboardButton('22о')
        nn3 = types.KeyboardButton('23о')
        tn3 = types.KeyboardButton('24о')
        one3 = types.KeyboardButton('25о')
        sx2 = types.KeyboardButton('26о')
        markup.add(one, tw, thr, fr, fv, sx, sw, ei, nn, tn, one1, tw1, thr1, fr1, fv1, sx1, sw1, ei1, nn1, tn1, one2,ei3, nn3, tn3, one3, sx2)
        bot.send_message(message.chat.id, 'Выбери задание', reply_markup=markup)
    elif message.text == '1о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=354')
        otr(message)
    elif message.text == '2о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=355')
        otr(message)
    elif message.text == '3о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=356')
        otr(message)
    elif message.text == '4о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=340')
        otr(message)
    elif message.text == '5о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/')
        otr(message)
    elif message.text == '6о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=353')
        otr(message)
    elif message.text == '7о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=287')
        otr(message)
    elif message.text == '8о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=333')
        otr(message)

    elif message.text == '9о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=358')
        otr(message)
    elif message.text == '10о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=348')
        otr(message)
    elif message.text == '11о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=351')
        otr(message)
    elif message.text == '12о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=350')
        otr(message)
    elif message.text == '13о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=272')
        otr(message)
    elif message.text == '14о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=273')
        otr(message)
    elif message.text == '15о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=267')
        otr(message)
    elif message.text == '16о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=277')
        otr(message)
    elif message.text == '17о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=275')
        otr(message)
    elif message.text == '18о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=306')
        otr(message)
    elif message.text == '19о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=309')
        otr(message)
    elif message.text == '20о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=280')
        otr(message)

    elif message.text == '21о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=364')
        otr(message)

    elif message.text == '22о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=361')
        otr(message)
    elif message.text == '23о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=283')
        otr(message)
    elif message.text == '24о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=284')
        otr(message)
    elif message.text == '25о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=253')
        otr(message)
    elif message.text == '26о':
        bot.send_message(message.chat.id,
                         'Если  хочешь отработать это задание, переходи по ссылке: https://rus-ege.sdamgia.ru/test?theme=239')
        otr(message)

def menu(message):
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=2)
    st = types.KeyboardButton('Структура')
    ex = types.KeyboardButton('Теория')
    markup.add(st, ex)
    bot.send_message(message.chat.id, "Что дальше:структура или теория?",
                     reply_markup=markup)

def paronim(message):
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=3)
    st = types.KeyboardButton('Структура')
    ex = types.KeyboardButton('Теория')
    par = types.KeyboardButton('Паронимы')
    markup.add(st, ex, par)
    bot.send_message(message.chat.id, "Что дальше:структура или теория?",
                     reply_markup=markup)

def orfo(message):
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=3)
    st = types.KeyboardButton('Структура')
    ex = types.KeyboardButton('Теория')
    sl = types.KeyboardButton('Орфографический')
    markup.add(st, ex, sl)
    bot.send_message(message.chat.id, "Что дальше:структура или теория?",
                     reply_markup=markup)

def teor(message):
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=3)
    st = types.KeyboardButton('Структура')
    ex = types.KeyboardButton('Теория')
    z = types.KeyboardButton('Теория к каждому заданию')
    markup.add(st, ex, z)
    bot.send_message(message.chat.id, "Что дальше:структура, теория или теория к каждому заданию?",
                     reply_markup=markup)

def otr(message):
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True, row_width=3)
    st = types.KeyboardButton('Структура')
    ex = types.KeyboardButton('Теория')
    ot = types.KeyboardButton('Отработкаа заданий')
    markup.add(st, ex, ot)
    bot.send_message(message.chat.id, "Что дальше:структура, теория или отработка заданий?",
                     reply_markup=markup)

bot.infinity_polling()


import uuid
from django.db import models
from django.utils import timezone

class Contact(models.Model):
    class Meta:
        db_table = 'contact'

    uuid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length = 150, null = False)
    email = models.EmailField(null = False, unique=True)
    phone = models.CharField(max_length=64,null=False)
    subject = models.CharField(max_length = 300, null = False)
    detail = models.TextField(null = False)
    status = models.IntegerField(null = False, default=0)

    deleted = models.BooleanField(default=False)
    created_at = models.DateField(auto_now_add=True)
    modified_at = models.DateField(auto_now=True)    # category = models.ForeignKey(Category, verbose_name='カテゴリ', on_delete=models.PROTECT,)

    def __str__(self):
        return self.subject


from arm.logicnode.arm_nodes import *

class DrawArcNode(ArmLogicTreeNode):
    """Draws an arc (part of a circle).

    @input Draw: Activate to draw the arc on this frame. The input must
        be (indirectly) called from an `On Render2D` node.
    @input Color: The color of the arc.
    @input Filled: Whether the arc is filled or only the outline is drawn.
    @input Strength: The line strength if the arc is not filled.
    @input Segments: How many line segments should be used to draw the
        arc. 0 (default) = automatic.
    @input Center X/Y: The position of the arc's center, in pixels from the top left corner.
    @input Radius: The radius of the arc in pixels.
    @input Start Angle/End Angle: The angles in radians where the
        arc starts/ends, starting right of the arc's center.
    @input Exterior Angle: Whether the angles describe an exterior angle.

    @output Out: Activated after the arc has been drawn.

    @see [`kha.graphics2.GraphicsExtension.drawArc()`](http://kha.tech/api/kha/graphics2/GraphicsExtension.html#drawArc).
    @see [`kha.graphics2.GraphicsExtension.fillArc()`](http://kha.tech/api/kha/graphics2/GraphicsExtension.html#fillArc).
    """
    bl_idname = 'LNDrawArcNode'
    bl_label = 'Draw Arc'
    arm_section = 'draw'
    arm_version = 1

    def arm_init(self, context):
        self.add_input('ArmNodeSocketAction', 'Draw')
        self.add_input('ArmColorSocket', 'Color', default_value=[1.0, 1.0, 1.0, 1.0])
        self.add_input('ArmBoolSocket', 'Filled', default_value=False)
        self.add_input('ArmFloatSocket', 'Strength', default_value=1.0)
        self.add_input('ArmIntSocket', 'Segments')
        self.add_input('ArmFloatSocket', 'Center X')
        self.add_input('ArmFloatSocket', 'Center Y')
        self.add_input('ArmFloatSocket', 'Radius', default_value=20.0)
        self.add_input('ArmFloatSocket', 'Start Angle')
        self.add_input('ArmFloatSocket', 'End Angle')
        self.add_input('ArmBoolSocket', 'Exterior Angle', default_value=False)

        self.add_output('ArmNodeSocketAction', 'Out')


"""Module for test ignoring."""
import json
from typing import Optional

import constants
from helpers import output_handler

dis_reaction = output_handler.OutputReaction(
    prefix='test',
    module_name=__name__,
)

class BrokenTests(object):
    """Ignored tests representation."""

    def __init__(self, tests: list[dict], search_field: str = 'name'):
        """
        Init class instance.

        Args:
            tests (list[dict]): ignored tests
            search_field (str): field to process `self.get` method
        """
        self.search_field = search_field
        self._tests = tests

    @property
    def tests(self) -> list[dict]:
        """
        Getter for `self._tests`.

        Returns:
            self._tests (list[dict]): list of ignored tests
        """
        return self._tests

    @tests.setter
    def tests(self, tests_value: list[dict]):
        """
        Setter for `self._tests`.

        Args:
            tests_value (list[dict]): tests value to set up

        Raises:
            TypeError: if type error
            KeyError: if key error
        """
        if not isinstance(tests_value, list):
            raise TypeError('`tests` must be in `list` type.')

        for test_v in tests_value:
            if not isinstance(test_v, dict):
                raise TypeError('Each test must be in `dict` type.')

            if self.search_field not in test_v.keys():
                raise KeyError('Each test must have `name` field.')

        self._tests = tests_value

    def update(self, test_id: str):
        """
        Update test list.

        Args:
            test_id (str): test ID
        """
        if test_id not in self.get_tests_ids():

            try:
                self.tests.append(
                    {'name': test_id, 'reason': ''},
                )
            except Exception as exc:
                dis_reaction(
                    msg=['Failed to update tests.', exc],
                    severity=constants.SEV_ERROR,
                )

    def get(self, by_key: str) -> Optional[dict]:
        """
        Check for substring equality with test[self.search_field].

        Args:
            by_key (str): substring

        Returns:
            Optional[dict]: ignored test data if found
        """
        if self.tests:
            for test in self.tests:
                if test.get(self.search_field) == by_key:
                    return test

        return None

    def get_tests_ids(self) -> tuple:
        """
        Get all ignored tests IDs as tuple.

        Returns:
            ids (tuple): ignored tests ids
        """
        if self.tests:
            return tuple(test.get('name') for test in self.tests)

def load_broken_tests(source: str) -> BrokenTests:
    """
    Load ignored tests data.

    Args:
        source (str): source file with tests to load

    Returns:
        ignored_test_data (list[dict]): copy of ignored test data
    """
    try:
        with open(source, 'r') as dtf:
            return BrokenTests(
                json.load(dtf),
            )
    except Exception as exc:
        dis_reaction(
            msg=['Failed to load broken tests.', exc],
            severity=constants.SEV_WARNING,
        )


import tensorflow as tf
import numpy as np
#import cv2
import matplotlib.pyplot as plt

from tensorflow.keras import Model, Sequential, layers, utils
from tensorflow.keras.layers import Conv2D, Flatten, Dense, Activation,MaxPooling2D, Dropout, BatchNormalization
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from collections import Counter
import time
import os

class D2CNN(Model):

    def __init__(self, *args, **kwargs):
        super(D2CNN,self).__init__()
        self.conv1 = Sequential([
        Conv2D(10,(11,11),strides=4,padding='same',name = 'conv1_1'),
        Activation("relu",name = 'act1'),
        BatchNormalization(name = 'batch_norm_1'),
        MaxPooling2D(pool_size=(3,3),strides = 2, name = 'pool_1')
        ])
        self.conv2 = Sequential([
        Conv2D(20,(5,5),strides=1,padding='same',name = 'conv2_1'),
        Activation("relu",name = 'act2'),
        BatchNormalization(name = 'batch_norm_2'),
        MaxPooling2D(pool_size=(2,2),strides = 2, name = 'pool_2')
        ])
        self.conv3 = Sequential([
        Conv2D(40,(5,5),strides=1,padding='same',name = 'conv3_1'),
        Activation("relu",name = 'act3'),
        BatchNormalization(name = 'batch_norm_3'),
        MaxPooling2D(pool_size=(2,2),strides = 2, name = 'pool_3')
        ])
#         self.conv4 = Sequential([
#         Conv2D(256,(5,5),strides=1,padding='same',name = 'conv4_1'),
#         Activation("relu",name = 'act4'),
#         BatchNormalization(name = 'batch_norm_4'),
#         MaxPooling2D(pool_size=(2,2),strides = 2, name = 'pool_4')
#         ])

        self.flatten = Flatten()

        self.classifier =  Sequential([
        Dense(1024,activation = 'relu'),
        layers.Dropout(0.5),
        Dense(1024,activation = 'relu'),
        layers.Dropout(0.5),
        Dense(10,activation='softmax')
        ])

    def call(self,x):
        #x = tf.expand_dims(x,0)
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        #x = self.conv4(x)
        x = self.flatten(x)
        x = self.classifier(x)
        return x

#     def make(self, input_shape=(227,227,1)):
#
#         x = tf.keras.layers.Input(shape=input_shape)
#         model = tf.keras.Model(inputs=[x], outputs=self.call(x), name='actor')
#         print(model.summary())
#         return model

def data_work():

    train_data = np.load('data_train.npy') #add the training npy file path
    train_data = train_data.T
    t_label = np.load('t_train_corrected.npy') # add the training label npy file path
    bad_labels = np.where(t_label == -1)
    t_correct = np.delete(t_label,bad_labels[0])
    t_correct = t_correct.astype(np.int32)
    num_class = len(set(t_correct))
    t_final = utils.to_categorical(t_correct,num_classes=num_class)
    train_data_correct = np.delete(train_data,bad_labels[0],axis = 0)
    num_samp,dim = np.shape(train_data_correct)
    dim_2 = int(np.sqrt(dim))
    train_data_correct = train_data_correct.reshape(num_samp,dim_2,dim_2)
    data_final = train_data_correct.reshape(train_data_correct.shape+(1,))
    data_final = tf.image.resize_with_pad(data_final,227,227)

    return data_final,t_final

def self_plot(train,test,l1,l2,sav):
    fig = plt.figure(figsize=(18,9))
    ax1 = fig.add_subplot(1,1,1)
    ax1.plot(train,label = l1)
    ax1.plot(test,label = l2)
    ax1.legend()
    plt.savefig(sav+'.png')

def run():

    ti = str(time.ctime()).split()
    fol = 'model_4_' + str.join('_',ti)
    os.mkdir(fol)
    fil = 'model_4_' + str.join('_',ti)
    pth = os.path.join(fol,fil)

    dat,tar = data_work()

    datagen = ImageDataGenerator(rotation_range = 45,
                            width_shift_range = 0.2,
                            height_shift_range = 0.2,
                            shear_range = 0.2,
                            zoom_range = 0.2,
                            horizontal_flip = True,
                            fill_mode = 'nearest',
                            validation_split = 0.2,
                            featurewise_center= True,
                            featurewise_std_normalization= True)

    datagen.fit(dat)
    np.save(fol+'/data_mean',datagen.mean)
    np.save(fol+'/data_std',datagen.std)

    #gg_mean, gg_std = datagen.mean,datagen.std

    train_generator = datagen.flow(dat,tar,batch_size=32,
                                    subset='training')

    val_generator = datagen.flow(dat,tar,batch_size=8,subset='validation')

    '''call_back = tf.keras.callbacks.EarlyStopping(monitor='val_loss',
                                                 min_delta=0,
                                                 patience=20,
                                                 verbose=0,
                                                 mode='auto',
                                                 baseline=None,
                                                 restore_best_weights=True)'''

    call_back_2 = tf.keras.callbacks.ModelCheckpoint(filepath=pth,
                                                    monitor='val_accuracy',
                                                    mode='max',
                                                    save_weights_only= True)

    n_epoch = 250
    model = D2CNN()

    model.compile(optimizer = 'adam',
                loss = tf.keras.losses.CategoricalCrossentropy(),
                metrics = ['accuracy'])

    history = model.fit_generator(train_generator,
                        steps_per_epoch= (0.8*len(dat))//32,
                        validation_data = val_generator,
                        validation_steps = 8,
                        epochs = n_epoch,
                        callbacks = [call_back_2])

    self_plot(history.history['loss'],history.history['val_loss'],'training loss','testing_loss',fol+'/loss')
    self_plot(history.history['accuracy'],history.history['val_accuracy'],'training accuracy','testing_accuracy',fol+'/accuracy')

    model.save_weights(pth)
    model.save(f'model_4.md')

if __name__ == '__main__':
    run()


import vot
import sys
import cv2
import time
import torch
import numpy as np
import collections
import os.path

# make sure the paths you need are append
basedir = os.path.dirname(__file__)
sys.path.append(os.path.abspath(os.path.join(basedir, os.path.pardir)))

from modules.sample_generator import *
from modules.actor import Actor
# from option import *
# from data_prov import *

from modules.QNet_cir import QNet_cir
from modules.SiameseNet import SiameseNet
from modules.tem_policy_base import T_Policy
from modules.SiamFcTracker import SiamFCTracker
from modules.EmbeddingNet import BaselineEmbeddingNet

from utils.np2tensor import np2tensor
from utils.crop_image import crop_image_actor_
from utils.crop_image import move_crop_tracking

project_path = os.path.abspath(os.path.join(basedir, os.path.pardir))
T_N = 5

class DATracker(object):

    def __init__(self, image, region):

        self.window = max(region.width, region.height) * 2

        left = max(region.x, 0)
        top = max(region.y, 0)
        #
        # right = min(region.x + region.width, image.shape[1] - 1)
        # bottom = min(region.y + region.height, image.shape[0] - 1)

        self.position = (region.x + region.width / 2, region.y + region.height / 2)
        self.size = (region.width, region.height)

        self.siam = SiameseNet(BaselineEmbeddingNet())
        # weights_init(siam)
        siamfc_path = project_path + "/models/siamfc_pretrained.pth"

        pretrained_siam = torch.load(siamfc_path)
        siam_dict = self.siam.state_dict()
        pretrained_siam = {k: v for k, v in pretrained_siam.items() if k in siam_dict}
        siam_dict.update(pretrained_siam)
        self.siam.load_state_dict(siam_dict)

        self.pi = T_Policy(T_N)

        pretrained_pi_dict = torch.load(project_path + '/models/Qnet/template_policy/10400_template_policy.pth')
        pi_dict = self.pi.state_dict()
        pretrained_pi_dict = {k: v for k, v in pretrained_pi_dict.items() if k in pi_dict}
        # pretrained_pi_dict = {k: v for k, v in pretrained_pi_dict.items() if k in pi_dict and k.startswith("conv")}
        pi_dict.update(pretrained_pi_dict)
        self.pi.load_state_dict(pi_dict)

        self.q = QNet_cir()  # .load_state_dict(torch.load("../Models/500_actor.pth"))
        pretrained_q_dict = torch.load(project_path + "/models/Qnet/QLT/10400_Qnet.pth")
        q_dict = self.q.state_dict()
        pretrained_q_dict = {k: v for k, v in pretrained_q_dict.items() if k in q_dict}
        q_dict.update(pretrained_q_dict)
        self.q.load_state_dict(q_dict)
        self.tracker = SiamFCTracker(model_path=siamfc_path, gpu_id=0)
        if torch.cuda.is_available():
            self.siam = self.siam.cuda()
            self.pi = self.pi.cuda()
            self.q = self.q.cuda()
        init_bbox = np.array([left, top, region.width, region. height])
        self.rate = init_bbox[2] / init_bbox[3]
        self.template = self.tracker.init(image, init_bbox)
        self.templates = []
        for i in range(T_N):
            self.templates.append(self.template)

    def track(self, image):

        np_img = np.array(cv2.resize(image, (255, 255), interpolation=cv2.INTER_AREA)).transpose(2, 0, 1)
        np_imgs = []
        for i in range(T_N):
            np_imgs.append(np_img)

        with torch.no_grad():
            responses = self.siam(torch.Tensor(self.templates).permute(0, 3, 1, 2).float().cuda(), torch.Tensor(np_imgs).float().cuda())
            action = self.pi(responses.permute(1, 0, 2, 3).cuda()).cpu().detach().numpy()
        action_id = np.argmax(action)
        # print(action_id)
        if action[0][action_id] * 0.9 > action[0][0]:
            template = self.templates[action_id]
        else:
            template = self.templates[0]
        with torch.no_grad():
            siam_box = self.tracker.update(image, template)
        siam_box = np.round([siam_box[0], siam_box[1], siam_box[2] -siam_box[0], siam_box[3] - siam_box[1]])
        bbox = siam_box
        for i in range(5):
            img_crop_l, _, _ = crop_image_actor_(np.array(np_img), bbox)
            # imo_crop_l = (np.array(img_crop_l).reshape(3, 107, 107))
            imo_l = np2tensor(np.array(img_crop_l).reshape(1, 107, 107, 3))
            deta_pos = np.zeros(3)
            with torch.no_grad():
                action_q = self.q.sample_action(imo_l)
            deta = 0.04
            if (action_q == 0):
                break
            if (action_q == 1):
                deta_pos[1] -= deta
            if (action_q == 2):
                deta_pos[1] += deta
            if (action_q == 3):
                deta_pos[0] -= deta
            if (action_q == 4):
                deta_pos[0] += deta
            if (action_q == 5):
                deta_pos[2] += deta
            if (action_q == 6):
                deta_pos[2] -= deta

            pos_ = np.round(move_crop_tracking(np.array(siam_box), deta_pos, (image.shape[1], image.shape[0]), self.rate))
            bbox = pos_
        result = bbox
        return vot.Rectangle(result[0], result[1], result[2], result[3])

handle = vot.VOT("rectangle")
selection = handle.region()
imagefile = handle.frame()
if not imagefile:
    sys.exit(0)
rett = dict()
rett["imagefile"] = imagefile
image = cv2.imread(imagefile, cv2.COLOR_BGR2RGB)
# print(image)
tracker = DATracker(image, selection)
while True:
    imagefile = handle.frame()
    rett["imagefile"] = imagefile
    if not imagefile:
        break
    image = cv2.imread(imagefile, cv2.COLOR_BGR2RGB)
    region = tracker.track(image)
    handle.report(region,rett)