From 1045a54db26b6690a1ff610e7cba830566b77928 Mon Sep 17 00:00:00 2001 From: arthur Date: Tue, 28 Apr 2026 23:01:57 -0300 Subject: [PATCH 1/3] feat: new problem being formated. --- ra-preguicosa/Makefile | 97 + ra-preguicosa/maratona.cls | 188 + ra-preguicosa/problem.json | 64 + ra-preguicosa/src/ac.cpp | 8 + ra-preguicosa/src/checker.cpp | 12 + ra-preguicosa/src/generator.cpp | 83 + ra-preguicosa/src/script.sh | 1 + ra-preguicosa/src/testlib.h | 5963 +++++++++++++++++++++++ ra-preguicosa/src/validator.cpp | 44 + ra-preguicosa/statement/description.tex | 5 + ra-preguicosa/statement/input.tex | 6 + ra-preguicosa/statement/notes.tex | 0 ra-preguicosa/statement/output.tex | 2 + ra-preguicosa/statement/preamble.tex | 0 ra-preguicosa/statement/tutorial.tex | 0 15 files changed, 6473 insertions(+) create mode 100644 ra-preguicosa/Makefile create mode 100644 ra-preguicosa/maratona.cls create mode 100644 ra-preguicosa/problem.json create mode 100644 ra-preguicosa/src/ac.cpp create mode 100644 ra-preguicosa/src/checker.cpp create mode 100644 ra-preguicosa/src/generator.cpp create mode 100644 ra-preguicosa/src/script.sh create mode 100644 ra-preguicosa/src/testlib.h create mode 100644 ra-preguicosa/src/validator.cpp create mode 100644 ra-preguicosa/statement/description.tex create mode 100644 ra-preguicosa/statement/input.tex create mode 100644 ra-preguicosa/statement/notes.tex create mode 100644 ra-preguicosa/statement/output.tex create mode 100644 ra-preguicosa/statement/preamble.tex create mode 100644 ra-preguicosa/statement/tutorial.tex diff --git a/ra-preguicosa/Makefile b/ra-preguicosa/Makefile new file mode 100644 index 0000000..4227f1a --- /dev/null +++ b/ra-preguicosa/Makefile @@ -0,0 +1,97 @@ +# Normal directories +SRC_DIR := src +BIN_DIR := bin +DBG_DIR := bin/debug + +# Grader directories +GRADER := $(wildcard $(SRC_DIR)/grader.cpp) +GRADER_DIR := $(SRC_DIR)/grader +HANDLER_DIR := $(SRC_DIR)/handler + +GRADER_SRC := $(wildcard $(GRADER_DIR)/*.cpp) +GRADER_BIN := $(patsubst $(GRADER_DIR)/%.cpp, $(BIN_DIR)/%, $(GRADER_SRC)) +GRADER_DBG := $(patsubst $(GRADER_DIR)/%.cpp, $(DBG_DIR)/%, $(GRADER_SRC)) + +# Change CPP source directories if grader is defined +ifdef GRADER + SRC := $(wildcard $(HANDLER_DIR)/*.cpp) + BIN := $(patsubst $(HANDLER_DIR)/%.cpp, $(BIN_DIR)/%, $(SRC)) + DBG := $(patsubst $(HANDLER_DIR)/%.cpp, $(DBG_DIR)/%, $(SRC)) +else + SRC := $(wildcard $(SRC_DIR)/*.cpp) + BIN := $(patsubst $(SRC_DIR)/%.cpp, $(BIN_DIR)/%, $(SRC)) + DBG := $(patsubst $(SRC_DIR)/%.cpp, $(DBG_DIR)/%, $(SRC)) +endif + +SRC_C := $(wildcard $(SRC_DIR)/*.c) +BIN_C := $(patsubst $(SRC_DIR)/%.c, $(BIN_DIR)/%, $(SRC_C)) +DBG_C := $(patsubst $(SRC_DIR)/%.c, $(DBG_DIR)/%, $(SRC_C)) + +SRC_JAVA := $(wildcard $(SRC_DIR)/*.java) +BIN_JAVA := $(patsubst $(SRC_DIR)/%.java, $(BIN_DIR)/%.class, $(SRC_JAVA)) +DBG_JAVA := $(patsubst $(SRC_DIR)/%.java, $(DBG_DIR)/%.class, $(SRC_JAVA)) + +CHECKER := $(wildcard $(SRC_DIR)/checker.cpp) + +C := gcc +CPP := g++ +CXX_FLAGS := -Wall -O2 +DEBUG_FLAGS := -Wall -g +BOCA_FLAGS := -static -DBOCA_SUPPORT + +JV = javac +JV_DEBUG = -g +JV_DIR = -d bin +JV_DBG_DIR = -d bin/debug + +.PHONY: all debug release checker clean + +all: debug release checker + +debug: $(DBG) $(DBG_C) $(DBG_JAVA) $(GRADER_DBG) + +release: $(BIN) $(BIN_C) $(BIN_JAVA) $(GRADER_BIN) + +ifdef CHECKER +checker: $(DBG_DIR)/checker-boca $(BIN_DIR)/checker-boca +endif + +$(BIN): $(BIN_DIR)/% : $(SRC_DIR)/%.cpp | $(BIN_DIR) + $(CPP) $(CXX_FLAGS) $^ -o $@ + +$(DBG): $(DBG_DIR)/% : $(SRC_DIR)/%.cpp | $(DBG_DIR) + $(CPP) $(DEBUG_FLAGS) $^ -o $@ + +$(BIN_C): $(BIN_DIR)/% : $(SRC_DIR)/%.c | $(BIN_DIR) + $(C) $(CXX_FLAGS) $^ -o $@ + +$(DBG_C): $(DBG_DIR)/% : $(SRC_DIR)/%.c | $(DBG_DIR) + $(C) $(DEBUG_FLAGS) $^ -o $@ + +$(BIN_JAVA): $(BIN_DIR)/%.class : $(SRC_DIR)/%.java | $(BIN_DIR) + $(JV) $(JV_DIR) $^ + +$(DBG_JAVA): $(DBG_DIR)/%.class : $(SRC_DIR)/%.java | $(DBG_DIR) + $(JV) $(JV_DEBUG) $(JV_DBG_DIR) $^ + +$(GRADER_BIN): $(BIN_DIR)/% : $(GRADER_DIR)/%.cpp $(GRADER) $(GRADER_DIR)/*.h + $(CPP) $(CXX_FLAGS) $^ -o $@ + +$(GRADER_DBG): $(DBG_DIR)/% : $(GRADER_DIR)/%.cpp $(GRADER) $(GRADER_DIR)/*.h + $(CPP) $(DEBUG_FLAGS) $^ -o $@ + +$(BIN_DIR): + mkdir -p $@ + +$(DBG_DIR): + mkdir -p $@ + +$(BIN_DIR)/checker-boca: $(SRC_DIR)/checker.cpp + $(CPP) $(CXX_FLAGS) $(BOCA_FLAGS) $^ -o $@ + +$(DBG_DIR)/checker-boca: $(SRC_DIR)/checker.cpp + $(CPP) $(DEBUG_FLAGS) $(BOCA_FLAGS) $^ -o $@ + +clean: + @echo Cleaning problem files + rm -rf bin diff --git a/ra-preguicosa/maratona.cls b/ra-preguicosa/maratona.cls new file mode 100644 index 0000000..e11d53d --- /dev/null +++ b/ra-preguicosa/maratona.cls @@ -0,0 +1,188 @@ +\ProvidesPackage{maratona} +\LoadClass[11pt]{article} + +% remove page numbers +\pagenumbering{gobble} + +\RequirePackage{fancyhdr} + +\RequirePackage{tabularx,colortbl} + +%\RequirePackage{arial} +\RequirePackage{ifpdf} +\RequirePackage[T1]{fontenc} +\RequirePackage[utf8]{inputenc} +\RequirePackage[portuguese]{babel} +\RequirePackage{graphics} +\RequirePackage{graphicx} +\RequirePackage{amssymb,amsmath,wrapfig} +\RequirePackage{xcolor,colortbl} +\RequirePackage{xcolor} +\RequirePackage{ifthen} +\oddsidemargin 0cm +\evensidemargin -2cm +\topmargin -1cm +\textwidth 16cm +\textheight 23cm + +\ifpdf +\RequirePackage[pdftex]{hyperref} +\else +\RequirePackage[hypertex]{hyperref} +\fi + + +\newcommand{\var}[1]{\ensuremath{{#1}}} + + +\hypersetup{ + letterpaper, + colorlinks=true, + linkcolor=blue, + urlcolor=blue, + pdfpagemode=none, + pdftitle={IV Maratona de Programação do IFB \today}, + pdfauthor={}, + pdfsubject={Caderno de problemas da IV Maratona de Programação do IFB }, + pdfkeywords={maratona, programação, IFB} +} + + + +\DeclareGraphicsExtensions{png} + +\lhead{DS Contest Tools} +\pagestyle{fancy} + +% Capa +\newenvironment{Maratona}[3] +{ + \begin{titlepage} + \begin{center} + + \vspace{1cm} + \Large{\textbf{#1}} \\ + \vspace{1cm} + {\textbf{Caderno de Problemas}} \\ + \vspace{1cm} + \begin{small} + \textsl{#2} + \end{small} \\ + \begin{figure}[htp] + \begin{center} + \includegraphics[scale=1]{logos/logo-maratona.png} + \end{center} + \end{figure} + {(Este caderno contém {#3} problemas)} \\ + \vspace{1cm} + } + { + \vfill + \begin{small} + {QNM 40, Área Especial nº 01, + Taguatinga/DF, 72146-000 , + Brasil } \\ + {Telefone (61) 2103-2200 \\http://www.ifb.edu.br/taguatinga} \\ + \end{small} + \end{center} + \end{titlepage} +} + +\newcommand{\Organizacao}[2]{ + {\small \vfill + \begin{center} + + \textbf{Comissão Organizadora:} \\ + {#1} \\ + \bigskip + \textbf{Apoio:}\\ + {#2} + \end{center} + } + \vfill +} + + +% Problema +\newcounter{problem} +\newenvironment{Problema}[4]{ + \stepcounter{problem} + \newpage + \begin{center} + \Large{\ifthenelse{\equal{#1}{}}{\textbf{{#2}}}{\textbf{Problema {#1} -- {#2} }}}{\\\footnotesize \textbf{Limite de tempo: {#3}s}}{\\[-0.1cm]\footnotesize \textbf{Limite de memória: {#4}MB}} + \end{center} +} + +\newcounter{problemAutor} +\newenvironment{ProblemaAutor}[5]{ + \stepcounter{problemAutor} + \newpage + \begin{center} + \Large{\ifthenelse{\equal{#1}{}}{\textbf{{#2}}}{\textbf{Problema {#1} -- {#2} }}}{\\\footnotesize \textbf{Limite de tempo: {#3}s}}{\\[-0.1cm]\footnotesize \textbf{Limite de memória: {#4}MB\\}}{ + \footnotesize Autor: {#5} + } + \end{center} +} + + +% Código-fonte +\newcommand{\codigofonte}[1]{Nome do arquivo fonte: {#1}} + +% Entrada +\newcommand{\Entrada}{ + \bigskip + \begin{large} + \textbf{Entrada} \\ + \end{large} +} + +% Saida +\newcommand{\Saida}{ + \bigskip + \begin{large} + \textbf{Saída} \\ + \end{large} +} + +\newcommand{\Interacao}{ + \bigskip + \begin{large} + \textbf{Interação} \\ + \end{large} +} + +\newcommand{\Notas}{ + \bigskip + \begin{large} + \textbf{Notas} \\ + \end{large} +} + +% Exemplo +\newenvironment{Exemplo} +{ + + \tabularx{\textwidth}{XX} + % {@{\extracolsep{\fill}}|l|l|} + % {|l|l@{\extracolsep{\fill}|}} + \hline + Entrada & Saída \\\hline +} +{ + \hline + \endtabularx +} + +% Exemplo de Entrada +\newenvironment{ExemploEntrada} +{ + \bigskip + \begin{large} + \textbf{Exemplo} \\ + \end{large} +} +{ +} + +% Sample Output + diff --git a/ra-preguicosa/problem.json b/ra-preguicosa/problem.json new file mode 100644 index 0000000..8f2f975 --- /dev/null +++ b/ra-preguicosa/problem.json @@ -0,0 +1,64 @@ +{ + "version": "1.0", + "problem": { + "title": "A rã saltadora preguiçosa", + "event": "", + "time_limit": 1.0, + "memory_limit_mb": 1536, + "input_file": "stdin", + "output_file": "stdout", + "interactive": false, + "grader": false, + "subject": { + "en_us": [ + "" + ], + "pt_br": [ + "" + ], + "es": [ + "" + ] + } + }, + "author": { + "name": "SPOJ - RAPREGUI", + "affiliation": "", + "country": "", + "email": "" + }, + "build": { + "run_generator": true, + "run_validator": true, + "produce_outputs": true, + "run_checker": true, + "run_all_solutions": true, + "run_specific_solution": "", + "generate_io_only": false, + "generate_pdf_only": false, + "cpu_count": 1, + "build_pdf": true, + "pdf_format": "ds", + "io_samples": 3 + }, + "solutions": { + "main-ac": "", + "alternative-ac": [], + "wrong-answer": [], + "time-limit": [], + "time-limit-or-ac": [], + "time-limit-or-memory-limit": [], + "memory-limit": [], + "presentation-error": [], + "runtime-error": [] + }, + "polygon_config": { + "id": "" + }, + "boca_config": { + "time_limit": 1, + "number_of_repetitions": 1, + "maximum_memory_mb": 1536, + "maximum_output_size_kb": 24096 + } +} \ No newline at end of file diff --git a/ra-preguicosa/src/ac.cpp b/ra-preguicosa/src/ac.cpp new file mode 100644 index 0000000..0b2cb0b --- /dev/null +++ b/ra-preguicosa/src/ac.cpp @@ -0,0 +1,8 @@ +#include + +using namespace std; + + +int main(){ + return 0; +} \ No newline at end of file diff --git a/ra-preguicosa/src/checker.cpp b/ra-preguicosa/src/checker.cpp new file mode 100644 index 0000000..2255902 --- /dev/null +++ b/ra-preguicosa/src/checker.cpp @@ -0,0 +1,12 @@ +#include "testlib.h" +#include + + +using namespace std; + + +int main(int argc, char* argv[]) { + setName("Set the name of your checker here"); + registerTestlibCmd(argc, argv); + return 0; +} \ No newline at end of file diff --git a/ra-preguicosa/src/generator.cpp b/ra-preguicosa/src/generator.cpp new file mode 100644 index 0000000..ee8316e --- /dev/null +++ b/ra-preguicosa/src/generator.cpp @@ -0,0 +1,83 @@ +#include "testlib.h" +#include + +using namespace std; + +const int MIN_N = 0; +const int MAX_N = 100; + +const int rnd_test_n = 100; + +template void append(vector &dest, const vector &orig) { + dest.insert(dest.end(), orig.begin(), orig.end()); +} + +string output_tc(int x, int y) { + ostringstream oss; + oss << x << " " << y << endl; + return oss.str(); +} + +vector generate_sample_tests() { + vector tests; + tests.push_back(output_tc(1, 1)); + tests.push_back(output_tc(2, 2)); + tests.push_back(output_tc(0, 0)); + return tests; +} + +vector generate_manual_tests() { + vector tests; + tests.push_back(output_tc(100, 0)); + tests.push_back(output_tc(0, 100)); + return tests; +} + +string rnd_test(int i){ + int min_n = MIN_N; + int max_n = MAX_N; + + if(i generate_random_tests() { + vector tests; + for (int i = 0; i < rnd_test_n; i++){ + tests.push_back(rnd_test(i)); + } + return tests; +} + +string extreme_test_1(){ + return(output_tc(100, 100)); +} + +vector generate_extreme_tests(){ + vector tests; + tests.push_back(extreme_test_1()); + return tests; +} + +int main(int argc, char *argv[]) { + registerGen(argc, argv, 1); + vector tests; + size_t test = 0; + append(tests, generate_sample_tests()); + append(tests, generate_manual_tests()); + append(tests, generate_random_tests()); + append(tests, generate_extreme_tests()); + for (const auto &t : tests) { + startTest(++test); + cout << t; + } + return 0; +} \ No newline at end of file diff --git a/ra-preguicosa/src/script.sh b/ra-preguicosa/src/script.sh new file mode 100644 index 0000000..a8a6bda --- /dev/null +++ b/ra-preguicosa/src/script.sh @@ -0,0 +1 @@ +generator \ No newline at end of file diff --git a/ra-preguicosa/src/testlib.h b/ra-preguicosa/src/testlib.h new file mode 100644 index 0000000..fac02ad --- /dev/null +++ b/ra-preguicosa/src/testlib.h @@ -0,0 +1,5963 @@ +/* + * It is strictly recommended to include "testlib.h" before any other include + * in your code. In this case testlib overrides compiler specific "random()". + * + * If you can't compile your code and compiler outputs something about + * ambiguous call of "random_shuffle", "rand" or "srand" it means that + * you shouldn't use them. Use "shuffle", and "rnd.next()" instead of them + * because these calls produce stable result for any C++ compiler. Read + * sample generator sources for clarification. + * + * Please read the documentation for class "random_t" and use "rnd" instance in + * generators. Probably, these sample calls will be usefull for you: + * rnd.next(); rnd.next(100); rnd.next(1, 2); + * rnd.next(3.14); rnd.next("[a-z]{1,100}"). + * + * Also read about wnext() to generate off-center random distribution. + * + * See https://github.com/MikeMirzayanov/testlib/ to get latest version or bug tracker. + */ + +#ifndef _TESTLIB_H_ +#define _TESTLIB_H_ + +/* + * Copyright (c) 2005-2022 + */ + +#define VERSION "0.9.40-SNAPSHOT" + +/* + * Mike Mirzayanov + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use or copy this software for any purpose is hereby granted + * without fee, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ + +/* NOTE: This file contains testlib library for C++. + * + * Check, using testlib running format: + * check.exe [ [-appes]], + * If result file is specified it will contain results. + * + * Validator, using testlib running format: + * validator.exe < input.txt, + * It will return non-zero exit code and writes message to standard output. + * + * Generator, using testlib running format: + * gen.exe [parameter-1] [parameter-2] [... paramerter-n] + * You can write generated test(s) into standard output or into the file(s). + * + * Interactor, using testlib running format: + * interactor.exe [ [ [-appes]]], + * Reads test from inf (mapped to args[1]), writes result to tout (mapped to argv[2], + * can be judged by checker later), reads program output from ouf (mapped to stdin), + * writes output to program via stdout (use cout, printf, etc). + */ + +const char *latestFeatures[] = { + "Supported '--testMarkupFileName fn' and '--testCase tc/--testCaseFileName fn' for validators", + "Added opt defaults via opt(key/index, default_val); check unused opts when using has_opt or default opt (turn off this check with suppressEnsureNoUnusedOpt()).", + "For checker added --group and --testset command line params (like for validator), use checker.group() or checker.testset() to get values", + "Added quitpi(points_info, message) function to return with _points exit code 7 and given points_info", + "rnd.partition(size, sum[, min_part=1]) returns random (unsorted) partition which is a representation of the given `sum` as a sum of `size` positive integers (or >=min_part if specified)", + "rnd.distinct(size, n) and rnd.distinct(size, from, to)", + "opt(\"some_missing_key\") returns false now", + "has_opt(key)", + "Abort validator on validator.testset()/validator.group() if registered without using command line", + "Print integer range violations in a human readable way like `violates the range [1, 10^9]`", + "Opts supported: use them like n = opt(\"n\"), in a command line you can use an exponential notation", + "Reformatted", + "Use setTestCase(i) or unsetTestCase() to support test cases (you can use it in any type of program: generator, interactor, validator or checker)", + "Fixed issue #87: readStrictDouble accepts \"-0.00\"", + "Fixed issue #83: added InStream::quitif(condition, ...)", + "Fixed issue #79: fixed missed guard against repeated header include", + "Fixed issue #80: fixed UB in case of huge quitf message", + "Fixed issue #84: added readXs(size, indexBase = 1)", + "Fixed stringstream repeated usage issue", + "Fixed compilation in g++ (for std=c++03)", + "Batch of println functions (support collections, iterator ranges)", + "Introduced rnd.perm(size, first = 0) to generate a `first`-indexed permutation", + "Allow any whitespace in readInts-like functions for non-validators", + "Ignore 4+ command line arguments ifdef EJUDGE", + "Speed up of vtos", + "Show line number in validators in case of incorrect format", + "Truncate huge checker/validator/interactor message", + "Fixed issue with readTokenTo of very long tokens, now aborts with _pe/_fail depending of a stream type", + "Introduced InStream::ensure/ensuref checking a condition, returns wa/fail depending of a stream type", + "Fixed compilation in VS 2015+", + "Introduced space-separated read functions: readWords/readTokens, multilines read functions: readStrings/readLines", + "Introduced space-separated read functions: readInts/readIntegers/readLongs/readUnsignedLongs/readDoubles/readReals/readStrictDoubles/readStrictReals", + "Introduced split/tokenize functions to separate string by given char", + "Introduced InStream::readUnsignedLong and InStream::readLong with unsigned long long paramerters", + "Supported --testOverviewLogFileName for validator: bounds hits + features", + "Fixed UB (sequence points) in random_t", + "POINTS_EXIT_CODE returned back to 7 (instead of 0)", + "Removed disable buffers for interactive problems, because it works unexpectedly in wine", + "InStream over string: constructor of InStream from base InStream to inherit policies and std::string", + "Added expectedButFound quit function, examples: expectedButFound(_wa, 10, 20), expectedButFound(_fail, ja, pa, \"[n=%d,m=%d]\", n, m)", + "Fixed incorrect interval parsing in patterns", + "Use registerGen(argc, argv, 1) to develop new generator, use registerGen(argc, argv, 0) to compile old generators (originally created for testlib under 0.8.7)", + "Introduced disableFinalizeGuard() to switch off finalization checkings", + "Use join() functions to format a range of items as a single string (separated by spaces or other separators)", + "Use -DENABLE_UNEXPECTED_EOF to enable special exit code (by default, 8) in case of unexpected eof. It is good idea to use it in interactors", + "Use -DUSE_RND_AS_BEFORE_087 to compile in compatibility mode with random behavior of versions before 0.8.7", + "Fixed bug with nan in stringToDouble", + "Fixed issue around overloads for size_t on x64", + "Added attribute 'points' to the XML output in case of result=_points", + "Exit codes can be customized via macros, e.g. -DPE_EXIT_CODE=14", + "Introduced InStream function readWordTo/readTokenTo/readStringTo/readLineTo for faster reading", + "Introduced global functions: format(), englishEnding(), upperCase(), lowerCase(), compress()", + "Manual buffer in InStreams, some IO speed improvements", + "Introduced quitif(bool, const char* pattern, ...) which delegates to quitf() in case of first argument is true", + "Introduced guard against missed quitf() in checker or readEof() in validators", + "Supported readStrictReal/readStrictDouble - to use in validators to check strictly float numbers", + "Supported registerInteraction(argc, argv)", + "Print checker message to the stderr instead of stdout", + "Supported TResult _points to output calculated score, use quitp(...) functions", + "Fixed to be compilable on Mac", + "PC_BASE_EXIT_CODE=50 in case of defined TESTSYS", + "Fixed issues 19-21, added __attribute__ format printf", + "Some bug fixes", + "ouf.readInt(1, 100) and similar calls return WA", + "Modified random_t to avoid integer overflow", + "Truncated checker output [patch by Stepan Gatilov]", + "Renamed class random -> class random_t", + "Supported name parameter for read-and-validation methods, like readInt(1, 2, \"n\")", + "Fixed bug in readDouble()", + "Improved ensuref(), fixed nextLine to work in case of EOF, added startTest()", + "Supported \"partially correct\", example: quitf(_pc(13), \"result=%d\", result)", + "Added shuffle(begin, end), use it instead of random_shuffle(begin, end)", + "Added readLine(const string& ptrn), fixed the logic of readLine() in the validation mode", + "Package extended with samples of generators and validators", + "Written the documentation for classes and public methods in testlib.h", + "Implemented random routine to support generators, use registerGen() to switch it on", + "Implemented strict mode to validate tests, use registerValidation() to switch it on", + "Now ncmp.cpp and wcmp.cpp are return WA if answer is suffix or prefix of the output", + "Added InStream::readLong() and removed InStream::readLongint()", + "Now no footer added to each report by default (use directive FOOTER to switch on)", + "Now every checker has a name, use setName(const char* format, ...) to set it", + "Now it is compatible with TTS (by Kittens Computing)", + "Added \'ensure(condition, message = \"\")\' feature, it works like assert()", + "Fixed compatibility with MS C++ 7.1", + "Added footer with exit code information", + "Added compatibility with EJUDGE (compile with EJUDGE directive)", + "Added compatibility with Contester (compile with CONTESTER directive)" +}; + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NO_VA_START_VALIDATION +#endif + +/* Overrides random() for Borland C++. */ +#define random __random_deprecated +#include +#include +#include +#include +#undef random + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef TESTLIB_THROW_EXIT_EXCEPTION_INSTEAD_OF_EXIT +# include +#endif + +#if (_WIN32 || __WIN32__ || __WIN32 || _WIN64 || __WIN64__ || __WIN64 || WINNT || __WINNT || __WINNT__ || __CYGWIN__) +# if !defined(_MSC_VER) || _MSC_VER > 1400 +# define NOMINMAX 1 +# include +# else +# define WORD unsigned short +# include +# endif +# include +# define ON_WINDOWS +# if defined(_MSC_VER) && _MSC_VER > 1400 +# pragma warning( disable : 4127 ) +# pragma warning( disable : 4146 ) +# pragma warning( disable : 4458 ) +# endif +#else +# define WORD unsigned short +# include +#endif + +#if defined(FOR_WINDOWS) && defined(FOR_LINUX) +#error Only one target system is allowed +#endif + +#ifndef LLONG_MIN +#define LLONG_MIN (-9223372036854775807LL - 1) +#endif + +#ifndef ULLONG_MAX +#define ULLONG_MAX (18446744073709551615) +#endif + +#define LF ((char)10) +#define CR ((char)13) +#define TAB ((char)9) +#define SPACE ((char)' ') +#define EOFC (255) + +#ifndef OK_EXIT_CODE +# ifdef CONTESTER +# define OK_EXIT_CODE 0xAC +# elif defined BOCA_SUPPORT +# define OK_EXIT_CODE 4 +# else +# define OK_EXIT_CODE 0 +# endif +#endif + +#ifndef WA_EXIT_CODE +# ifdef EJUDGE +# define WA_EXIT_CODE 5 +# elif defined(CONTESTER) +# define WA_EXIT_CODE 0xAB +# elif defined BOCA_SUPPORT +# define WA_EXIT_CODE 6 +# else +# define WA_EXIT_CODE 1 +# endif +#endif + +#ifndef PE_EXIT_CODE +# ifdef EJUDGE +# define PE_EXIT_CODE 4 +# elif defined(CONTESTER) +# define PE_EXIT_CODE 0xAA +# elif defined BOCA_SUPPORT +# define PE_EXIT_CODE 6 +# else +# define PE_EXIT_CODE 2 +# endif +#endif + +#ifndef FAIL_EXIT_CODE +# ifdef EJUDGE +# define FAIL_EXIT_CODE 6 +# elif defined(CONTESTER) +# define FAIL_EXIT_CODE 0xA3 +# elif defined BOCA_SUPPORT +# define FAIL_EXIT_CODE 7 +# else +# define FAIL_EXIT_CODE 3 +# endif +#endif + +#ifndef DIRT_EXIT_CODE +# ifdef EJUDGE +# define DIRT_EXIT_CODE 6 +# else +# define DIRT_EXIT_CODE 4 +# endif +#endif + +#ifndef POINTS_EXIT_CODE +# ifndef BOCA_SUPPORT +# define POINTS_EXIT_CODE 7 +# else +# define POINTS_EXIT_CODE 5 +# endif +#endif + +#ifndef UNEXPECTED_EOF_EXIT_CODE +# define UNEXPECTED_EOF_EXIT_CODE 8 +#endif + +#ifndef PC_BASE_EXIT_CODE +# ifdef TESTSYS +# define PC_BASE_EXIT_CODE 50 +# else +# define PC_BASE_EXIT_CODE 0 +# endif +#endif + +#ifdef __GNUC__ +# define __TESTLIB_STATIC_ASSERT(condition) typedef void* __testlib_static_assert_type[(condition) ? 1 : -1] __attribute__((unused)) +#else +# define __TESTLIB_STATIC_ASSERT(condition) typedef void* __testlib_static_assert_type[(condition) ? 1 : -1] +#endif + +#ifdef ON_WINDOWS +#define I64 "%I64d" +#define U64 "%I64u" +#else +#define I64 "%lld" +#define U64 "%llu" +#endif + +#ifdef _MSC_VER +# define NORETURN __declspec(noreturn) +#elif defined __GNUC__ +# define NORETURN __attribute__ ((noreturn)) +#else +# define NORETURN +#endif + +static char __testlib_format_buffer[16777216]; +static int __testlib_format_buffer_usage_count = 0; + +#define FMT_TO_RESULT(fmt, cstr, result) std::string result; \ + if (__testlib_format_buffer_usage_count != 0) \ + __testlib_fail("FMT_TO_RESULT::__testlib_format_buffer_usage_count != 0"); \ + __testlib_format_buffer_usage_count++; \ + va_list ap; \ + va_start(ap, fmt); \ + vsnprintf(__testlib_format_buffer, sizeof(__testlib_format_buffer), cstr, ap); \ + va_end(ap); \ + __testlib_format_buffer[sizeof(__testlib_format_buffer) - 1] = 0; \ + result = std::string(__testlib_format_buffer); \ + __testlib_format_buffer_usage_count--; \ + +const long long __TESTLIB_LONGLONG_MAX = 9223372036854775807LL; +const int __TESTLIB_MAX_TEST_CASE = 1073741823; + +int __testlib_exitCode; + +bool __testlib_hasTestCase; +int __testlib_testCase = -1; + +void setTestCase(int testCase); + +void unsetTestCase() { + __testlib_hasTestCase = false; + __testlib_testCase = -1; +} + +NORETURN static void __testlib_fail(const std::string &message); + +template +static inline T __testlib_abs(const T &x) { + return x > 0 ? x : -x; +} + +template +static inline T __testlib_min(const T &a, const T &b) { + return a < b ? a : b; +} + +template +static inline T __testlib_max(const T &a, const T &b) { + return a > b ? a : b; +} + +template +static inline T __testlib_crop(T value, T a, T b) { + return __testlib_min(__testlib_max(value, a), --b); +} + +static inline double __testlib_crop(double value, double a, double b) { + value = __testlib_min(__testlib_max(value, a), b); + if (value >= b) + value = std::nexttoward(b, a); + return value; +} + +static bool __testlib_prelimIsNaN(double r) { + volatile double ra = r; +#ifndef __BORLANDC__ + return ((ra != ra) == true) && ((ra == ra) == false) && ((1.0 > ra) == false) && ((1.0 < ra) == false); +#else + return std::_isnan(ra); +#endif +} + +static std::string removeDoubleTrailingZeroes(std::string value) { + while (!value.empty() && value[value.length() - 1] == '0' && value.find('.') != std::string::npos) + value = value.substr(0, value.length() - 1); + if (!value.empty() && value[value.length() - 1] == '.') + return value + '0'; + else + return value; +} + +#ifdef __GNUC__ +__attribute__ ((format (printf, 1, 2))) +#endif +std::string format(const char *fmt, ...) { + FMT_TO_RESULT(fmt, fmt, result); + return result; +} + +std::string format(const std::string fmt, ...) { + FMT_TO_RESULT(fmt, fmt.c_str(), result); + return result; +} + +static std::string __testlib_part(const std::string &s); + +static bool __testlib_isNaN(double r) { + __TESTLIB_STATIC_ASSERT(sizeof(double) == sizeof(long long)); + volatile double ra = r; + long long llr1, llr2; + std::memcpy((void *) &llr1, (void *) &ra, sizeof(double)); + ra = -ra; + std::memcpy((void *) &llr2, (void *) &ra, sizeof(double)); + long long llnan = 0xFFF8000000000000LL; + return __testlib_prelimIsNaN(r) || llnan == llr1 || llnan == llr2; +} + +static double __testlib_nan() { + __TESTLIB_STATIC_ASSERT(sizeof(double) == sizeof(long long)); +#ifndef NAN + long long llnan = 0xFFF8000000000000LL; + double nan; + std::memcpy(&nan, &llnan, sizeof(double)); + return nan; +#else + return NAN; +#endif +} + +static bool __testlib_isInfinite(double r) { + volatile double ra = r; + return (ra > 1E300 || ra < -1E300); +} + +#ifdef __GNUC__ +__attribute__((const)) +#endif +inline bool doubleCompare(double expected, double result, double MAX_DOUBLE_ERROR) { + MAX_DOUBLE_ERROR += 1E-15; + if (__testlib_isNaN(expected)) { + return __testlib_isNaN(result); + } else if (__testlib_isInfinite(expected)) { + if (expected > 0) { + return result > 0 && __testlib_isInfinite(result); + } else { + return result < 0 && __testlib_isInfinite(result); + } + } else if (__testlib_isNaN(result) || __testlib_isInfinite(result)) { + return false; + } else if (__testlib_abs(result - expected) <= MAX_DOUBLE_ERROR) { + return true; + } else { + double minv = __testlib_min(expected * (1.0 - MAX_DOUBLE_ERROR), + expected * (1.0 + MAX_DOUBLE_ERROR)); + double maxv = __testlib_max(expected * (1.0 - MAX_DOUBLE_ERROR), + expected * (1.0 + MAX_DOUBLE_ERROR)); + return result >= minv && result <= maxv; + } +} + +#ifdef __GNUC__ +__attribute__((const)) +#endif +inline double doubleDelta(double expected, double result) { + double absolute = __testlib_abs(result - expected); + + if (__testlib_abs(expected) > 1E-9) { + double relative = __testlib_abs(absolute / expected); + return __testlib_min(absolute, relative); + } else + return absolute; +} + +/** It does nothing on non-windows and files differ from stdin/stdout/stderr. */ +static void __testlib_set_binary(std::FILE *file) { + if (NULL != file) { +#ifdef ON_WINDOWS +# ifdef _O_BINARY + if (stdin == file) +# ifdef STDIN_FILENO + return void(_setmode(STDIN_FILENO, _O_BINARY)); +# else + return void(_setmode(_fileno(stdin), _O_BINARY)); +# endif + if (stdout == file) +# ifdef STDOUT_FILENO + return void(_setmode(STDOUT_FILENO, _O_BINARY)); +# else + return void(_setmode(_fileno(stdout), _O_BINARY)); +# endif + if (stderr == file) +# ifdef STDERR_FILENO + return void(_setmode(STDERR_FILENO, _O_BINARY)); +# else + return void(_setmode(_fileno(stderr), _O_BINARY)); +# endif +# elif O_BINARY + if (stdin == file) +# ifdef STDIN_FILENO + return void(setmode(STDIN_FILENO, O_BINARY)); +# else + return void(setmode(fileno(stdin), O_BINARY)); +# endif + if (stdout == file) +# ifdef STDOUT_FILENO + return void(setmode(STDOUT_FILENO, O_BINARY)); +# else + return void(setmode(fileno(stdout), O_BINARY)); +# endif + if (stderr == file) +# ifdef STDERR_FILENO + return void(setmode(STDERR_FILENO, O_BINARY)); +# else + return void(setmode(fileno(stderr), O_BINARY)); +# endif +# endif +#endif + } +} + +#if __cplusplus > 199711L || defined(_MSC_VER) +template +static std::string vtos(const T &t, std::true_type) { + if (t == 0) + return "0"; + else { + T n(t); + bool negative = n < 0; + std::string s; + while (n != 0) { + T digit = n % 10; + if (digit < 0) + digit = -digit; + s += char('0' + digit); + n /= 10; + } + std::reverse(s.begin(), s.end()); + return negative ? "-" + s : s; + } +} + +template +static std::string vtos(const T &t, std::false_type) { + std::string s; + static std::stringstream ss; + ss.str(std::string()); + ss.clear(); + ss << t; + ss >> s; + return s; +} + +template +static std::string vtos(const T &t) { + return vtos(t, std::is_integral()); +} + +/* signed case. */ +template +static std::string toHumanReadableString(const T &n, std::false_type) { + if (n == 0) + return vtos(n); + int trailingZeroCount = 0; + T n_ = n; + while (n_ % 10 == 0) + n_ /= 10, trailingZeroCount++; + if (trailingZeroCount >= 7) { + if (n_ == 1) + return "10^" + vtos(trailingZeroCount); + else if (n_ == -1) + return "-10^" + vtos(trailingZeroCount); + else + return vtos(n_) + "*10^" + vtos(trailingZeroCount); + } else + return vtos(n); +} + +/* unsigned case. */ +template +static std::string toHumanReadableString(const T &n, std::true_type) { + if (n == 0) + return vtos(n); + int trailingZeroCount = 0; + T n_ = n; + while (n_ % 10 == 0) + n_ /= 10, trailingZeroCount++; + if (trailingZeroCount >= 7) { + if (n_ == 1) + return "10^" + vtos(trailingZeroCount); + else + return vtos(n_) + "*10^" + vtos(trailingZeroCount); + } else + return vtos(n); +} + +template +static std::string toHumanReadableString(const T &n) { + return toHumanReadableString(n, std::is_unsigned()); +} +#else +template +static std::string vtos(const T& t) +{ + std::string s; + static std::stringstream ss; + ss.str(std::string()); + ss.clear(); + ss << t; + ss >> s; + return s; +} + +template +static std::string toHumanReadableString(const T &n) { + return vtos(n); +} +#endif + +template +static std::string toString(const T &t) { + return vtos(t); +} + +#if __cplusplus > 199711L || defined(_MSC_VER) +/* opts */ +void prepareOpts(int argc, char* argv[]); +#endif + +/* + * Very simple regex-like pattern. + * It used for two purposes: validation and generation. + * + * For example, pattern("[a-z]{1,5}").next(rnd) will return + * random string from lowercase latin letters with length + * from 1 to 5. It is easier to call rnd.next("[a-z]{1,5}") + * for the same effect. + * + * Another samples: + * "mike|john" will generate (match) "mike" or "john"; + * "-?[1-9][0-9]{0,3}" will generate (match) non-zero integers from -9999 to 9999; + * "id-([ac]|b{2})" will generate (match) "id-a", "id-bb", "id-c"; + * "[^0-9]*" will match sequences (empty or non-empty) without digits, you can't + * use it for generations. + * + * You can't use pattern for generation if it contains meta-symbol '*'. Also it + * is not recommended to use it for char-sets with meta-symbol '^' like [^a-z]. + * + * For matching very simple greedy algorithm is used. For example, pattern + * "[0-9]?1" will not match "1", because of greedy nature of matching. + * Alternations (meta-symbols "|") are processed with brute-force algorithm, so + * do not use many alternations in one expression. + * + * If you want to use one expression many times it is better to compile it into + * a single pattern like "pattern p("[a-z]+")". Later you can use + * "p.matches(std::string s)" or "p.next(random_t& rd)" to check matching or generate + * new string by pattern. + * + * Simpler way to read token and check it for pattern matching is "inf.readToken("[a-z]+")". + * + * All spaces are ignored in regex, unless escaped with \. For example, ouf.readLine("NO SOLUTION") + * will expect "NOSOLUTION", the correct call should be ouf.readLine("NO\\ SOLUTION") or + * ouf.readLine(R"(NO\ SOLUTION)") if you prefer raw string literals from C++11. + */ +class random_t; + +class pattern { +public: + /* Create pattern instance by string. */ + pattern(std::string s); + + /* Generate new string by pattern and given random_t. */ + std::string next(random_t &rnd) const; + + /* Checks if given string match the pattern. */ + bool matches(const std::string &s) const; + + /* Returns source string of the pattern. */ + std::string src() const; + +private: + bool matches(const std::string &s, size_t pos) const; + + std::string s; + std::vector children; + std::vector chars; + int from; + int to; +}; + +/* + * Use random_t instances to generate random values. It is preffered + * way to use randoms instead of rand() function or self-written + * randoms. + * + * Testlib defines global variable "rnd" of random_t class. + * Use registerGen(argc, argv, 1) to setup random_t seed be command + * line (to use latest random generator version). + * + * Random generates uniformly distributed values if another strategy is + * not specified explicitly. + */ +class random_t { +private: + unsigned long long seed; + static const unsigned long long multiplier; + static const unsigned long long addend; + static const unsigned long long mask; + static const int lim; + + long long nextBits(int bits) { + if (bits <= 48) { + seed = (seed * multiplier + addend) & mask; + return (long long) (seed >> (48 - bits)); + } else { + if (bits > 63) + __testlib_fail("random_t::nextBits(int bits): n must be less than 64"); + + int lowerBitCount = (random_t::version == 0 ? 31 : 32); + + long long left = (nextBits(31) << 32); + long long right = nextBits(lowerBitCount); + + return left ^ right; + } + } + +public: + static int version; + + /* New random_t with fixed seed. */ + random_t() + : seed(3905348978240129619LL) { + } + + /* Sets seed by command line. */ + void setSeed(int argc, char *argv[]) { + random_t p; + + seed = 3905348978240129619LL; + for (int i = 1; i < argc; i++) { + std::size_t le = std::strlen(argv[i]); + for (std::size_t j = 0; j < le; j++) + seed = seed * multiplier + (unsigned int) (argv[i][j]) + addend; + seed += multiplier / addend; + } + + seed = seed & mask; + } + + /* Sets seed by given value. */ + void setSeed(long long _seed) { + _seed = (_seed ^ multiplier) & mask; + seed = _seed; + } + +#ifndef __BORLANDC__ + + /* Random string value by given pattern (see pattern documentation). */ + std::string next(const std::string &ptrn) { + pattern p(ptrn); + return p.next(*this); + } + +#else + /* Random string value by given pattern (see pattern documentation). */ + std::string next(std::string ptrn) + { + pattern p(ptrn); + return p.next(*this); + } +#endif + + /* Random value in range [0, n-1]. */ + int next(int n) { + if (n <= 0) + __testlib_fail("random_t::next(int n): n must be positive"); + + if ((n & -n) == n) // n is a power of 2 + return (int) ((n * (long long) nextBits(31)) >> 31); + + const long long limit = INT_MAX / n * n; + + long long bits; + do { + bits = nextBits(31); + } while (bits >= limit); + + return int(bits % n); + } + + /* Random value in range [0, n-1]. */ + unsigned int next(unsigned int n) { + if (n >= INT_MAX) + __testlib_fail("random_t::next(unsigned int n): n must be less INT_MAX"); + return (unsigned int) next(int(n)); + } + + /* Random value in range [0, n-1]. */ + long long next(long long n) { + if (n <= 0) + __testlib_fail("random_t::next(long long n): n must be positive"); + + const long long limit = __TESTLIB_LONGLONG_MAX / n * n; + + long long bits; + do { + bits = nextBits(63); + } while (bits >= limit); + + return bits % n; + } + + /* Random value in range [0, n-1]. */ + unsigned long long next(unsigned long long n) { + if (n >= (unsigned long long) (__TESTLIB_LONGLONG_MAX)) + __testlib_fail("random_t::next(unsigned long long n): n must be less LONGLONG_MAX"); + return (unsigned long long) next((long long) (n)); + } + + /* Random value in range [0, n-1]. */ + long next(long n) { + return (long) next((long long) (n)); + } + + /* Random value in range [0, n-1]. */ + unsigned long next(unsigned long n) { + if (n >= (unsigned long) (LONG_MAX)) + __testlib_fail("random_t::next(unsigned long n): n must be less LONG_MAX"); + return (unsigned long) next((unsigned long long) (n)); + } + + /* Returns random value in range [from,to]. */ + int next(int from, int to) { + return int(next((long long) to - from + 1) + from); + } + + /* Returns random value in range [from,to]. */ + unsigned int next(unsigned int from, unsigned int to) { + return (unsigned int) (next((long long) to - from + 1) + from); + } + + /* Returns random value in range [from,to]. */ + long long next(long long from, long long to) { + return next(to - from + 1) + from; + } + + /* Returns random value in range [from,to]. */ + unsigned long long next(unsigned long long from, unsigned long long to) { + if (from > to) + __testlib_fail("random_t::next(unsigned long long from, unsigned long long to): from can't not exceed to"); + return next(to - from + 1) + from; + } + + /* Returns random value in range [from,to]. */ + long next(long from, long to) { + return next(to - from + 1) + from; + } + + /* Returns random value in range [from,to]. */ + unsigned long next(unsigned long from, unsigned long to) { + if (from > to) + __testlib_fail("random_t::next(unsigned long from, unsigned long to): from can't not exceed to"); + return next(to - from + 1) + from; + } + + /* Random double value in range [0, 1). */ + double next() { + long long left = ((long long) (nextBits(26)) << 27); + long long right = nextBits(27); + return __testlib_crop((double) (left + right) / (double) (1LL << 53), 0.0, 1.0); + } + + /* Random double value in range [0, n). */ + double next(double n) { + if (n <= 0.0) + __testlib_fail("random_t::next(double): n should be positive"); + return __testlib_crop(n * next(), 0.0, n); + } + + /* Random double value in range [from, to). */ + double next(double from, double to) { + if (from >= to) + __testlib_fail("random_t::next(double from, double to): from should be strictly less than to"); + return next(to - from) + from; + } + + /* Returns random element from container. */ + template + typename Container::value_type any(const Container &c) { + int size = int(c.size()); + if (size <= 0) + __testlib_fail("random_t::any(const Container& c): c.size() must be positive"); + return *(c.begin() + next(size)); + } + + /* Returns random element from iterator range. */ + template + typename Iter::value_type any(const Iter &begin, const Iter &end) { + int size = int(end - begin); + if (size <= 0) + __testlib_fail("random_t::any(const Iter& begin, const Iter& end): range must have positive length"); + return *(begin + next(size)); + } + + /* Random string value by given pattern (see pattern documentation). */ +#ifdef __GNUC__ + __attribute__ ((format (printf, 2, 3))) +#endif + std::string next(const char *format, ...) { + FMT_TO_RESULT(format, format, ptrn); + return next(ptrn); + } + + /* + * Weighted next. If type == 0 than it is usual "next()". + * + * If type = 1, than it returns "max(next(), next())" + * (the number of "max" functions equals to "type"). + * + * If type < 0, than "max" function replaces with "min". + */ + int wnext(int n, int type) { + if (n <= 0) + __testlib_fail("random_t::wnext(int n, int type): n must be positive"); + + if (abs(type) < random_t::lim) { + int result = next(n); + + for (int i = 0; i < +type; i++) + result = __testlib_max(result, next(n)); + + for (int i = 0; i < -type; i++) + result = __testlib_min(result, next(n)); + + return result; + } else { + double p; + + if (type > 0) + p = std::pow(next() + 0.0, 1.0 / (type + 1)); + else + p = 1 - std::pow(next() + 0.0, 1.0 / (-type + 1)); + + return __testlib_crop((int) (double(n) * p), 0, n); + } + } + + /* See wnext(int, int). It uses the same algorithms. */ + long long wnext(long long n, int type) { + if (n <= 0) + __testlib_fail("random_t::wnext(long long n, int type): n must be positive"); + + if (abs(type) < random_t::lim) { + long long result = next(n); + + for (int i = 0; i < +type; i++) + result = __testlib_max(result, next(n)); + + for (int i = 0; i < -type; i++) + result = __testlib_min(result, next(n)); + + return result; + } else { + double p; + + if (type > 0) + p = std::pow(next() + 0.0, 1.0 / (type + 1)); + else + p = 1 - std::pow(next() + 0.0, 1.0 / (-type + 1)); + + return __testlib_crop((long long) (double(n) * p), 0LL, n); + } + } + + /* Returns value in [0, n). See wnext(int, int). It uses the same algorithms. */ + double wnext(double n, int type) { + if (n <= 0) + __testlib_fail("random_t::wnext(double n, int type): n must be positive"); + + if (abs(type) < random_t::lim) { + double result = next(); + + for (int i = 0; i < +type; i++) + result = __testlib_max(result, next()); + + for (int i = 0; i < -type; i++) + result = __testlib_min(result, next()); + + return n * result; + } else { + double p; + + if (type > 0) + p = std::pow(next() + 0.0, 1.0 / (type + 1)); + else + p = 1 - std::pow(next() + 0.0, 1.0 / (-type + 1)); + + return __testlib_crop(n * p, 0.0, n); + } + } + + /* Returns value in [0, 1). See wnext(int, int). It uses the same algorithms. */ + double wnext(int type) { + return wnext(1.0, type); + } + + /* See wnext(int, int). It uses the same algorithms. */ + unsigned int wnext(unsigned int n, int type) { + if (n >= INT_MAX) + __testlib_fail("random_t::wnext(unsigned int n, int type): n must be less INT_MAX"); + return (unsigned int) wnext(int(n), type); + } + + /* See wnext(int, int). It uses the same algorithms. */ + unsigned long long wnext(unsigned long long n, int type) { + if (n >= (unsigned long long) (__TESTLIB_LONGLONG_MAX)) + __testlib_fail("random_t::wnext(unsigned long long n, int type): n must be less LONGLONG_MAX"); + + return (unsigned long long) wnext((long long) (n), type); + } + + /* See wnext(int, int). It uses the same algorithms. */ + long wnext(long n, int type) { + return (long) wnext((long long) (n), type); + } + + /* See wnext(int, int). It uses the same algorithms. */ + unsigned long wnext(unsigned long n, int type) { + if (n >= (unsigned long) (LONG_MAX)) + __testlib_fail("random_t::wnext(unsigned long n, int type): n must be less LONG_MAX"); + + return (unsigned long) wnext((unsigned long long) (n), type); + } + + /* Returns weighted random value in range [from, to]. */ + int wnext(int from, int to, int type) { + if (from > to) + __testlib_fail("random_t::wnext(int from, int to, int type): from can't not exceed to"); + return wnext(to - from + 1, type) + from; + } + + /* Returns weighted random value in range [from, to]. */ + int wnext(unsigned int from, unsigned int to, int type) { + if (from > to) + __testlib_fail("random_t::wnext(unsigned int from, unsigned int to, int type): from can't not exceed to"); + return int(wnext(to - from + 1, type) + from); + } + + /* Returns weighted random value in range [from, to]. */ + long long wnext(long long from, long long to, int type) { + if (from > to) + __testlib_fail("random_t::wnext(long long from, long long to, int type): from can't not exceed to"); + return wnext(to - from + 1, type) + from; + } + + /* Returns weighted random value in range [from, to]. */ + unsigned long long wnext(unsigned long long from, unsigned long long to, int type) { + if (from > to) + __testlib_fail( + "random_t::wnext(unsigned long long from, unsigned long long to, int type): from can't not exceed to"); + return wnext(to - from + 1, type) + from; + } + + /* Returns weighted random value in range [from, to]. */ + long wnext(long from, long to, int type) { + if (from > to) + __testlib_fail("random_t::wnext(long from, long to, int type): from can't not exceed to"); + return wnext(to - from + 1, type) + from; + } + + /* Returns weighted random value in range [from, to]. */ + unsigned long wnext(unsigned long from, unsigned long to, int type) { + if (from > to) + __testlib_fail("random_t::wnext(unsigned long from, unsigned long to, int type): from can't not exceed to"); + return wnext(to - from + 1, type) + from; + } + + /* Returns weighted random double value in range [from, to). */ + double wnext(double from, double to, int type) { + if (from >= to) + __testlib_fail("random_t::wnext(double from, double to, int type): from should be strictly less than to"); + return wnext(to - from, type) + from; + } + + /* Returns weighted random element from container. */ + template + typename Container::value_type wany(const Container &c, int type) { + size_t size = c.size(); + if (size <= 0) + __testlib_fail("random_t::wany(const Container& c, int type): c.size() must be positive"); + return *(c.begin() + wnext(size, type)); + } + + /* Returns weighted random element from iterator range. */ + template + typename Iter::value_type wany(const Iter &begin, const Iter &end, int type) { + int size = int(end - begin); + if (size <= 0) + __testlib_fail( + "random_t::any(const Iter& begin, const Iter& end, int type): range must have positive length"); + return *(begin + wnext(size, type)); + } + + /* Returns random permutation of the given size (values are between `first` and `first`+size-1)*/ + template + std::vector perm(T size, E first) { + if (size < 0) + __testlib_fail("random_t::perm(T size, E first = 0): size must non-negative"); + else if (size == 0) + return std::vector(); + std::vector p(size); + E current = first; + for (T i = 0; i < size; i++) + p[i] = current++; + if (size > 1) + for (T i = 1; i < size; i++) + std::swap(p[i], p[next(i + 1)]); + return p; + } + + /* Returns random permutation of the given size (values are between 0 and size-1)*/ + template + std::vector perm(T size) { + return perm(size, T(0)); + } + + /* Returns `size` unordered (unsorted) distinct numbers between `from` and `to`. */ + template + std::vector distinct(int size, T from, T to) { + std::vector result; + if (size == 0) + return result; + + if (from > to) + __testlib_fail("random_t::distinct expected from <= to"); + + if (size < 0) + __testlib_fail("random_t::distinct expected size >= 0"); + + uint64_t n = to - from + 1; + if (uint64_t(size) > n) + __testlib_fail("random_t::distinct expected size <= to - from + 1"); + + double expected = 0.0; + for (int i = 1; i <= size; i++) + expected += double(n) / double(n - i + 1); + + if (expected < double(n)) { + std::set vals; + while (int(vals.size()) < size) { + T x = T(next(from, to)); + if (vals.insert(x).second) + result.push_back(x); + } + } else { + if (n > 1000000000) + __testlib_fail("random_t::distinct here expected to - from + 1 <= 1000000000"); + std::vector p(perm(int(n), from)); + result.insert(result.end(), p.begin(), p.begin() + size); + } + + return result; + } + + /* Returns `size` unordered (unsorted) distinct numbers between `0` and `upper`-1. */ + template + std::vector distinct(int size, T upper) { + if (size < 0) + __testlib_fail("random_t::distinct expected size >= 0"); + if (size == 0) + return std::vector(); + + if (upper <= 0) + __testlib_fail("random_t::distinct expected upper > 0"); + if (size > upper) + __testlib_fail("random_t::distinct expected size <= upper"); + + return distinct(size, T(0), upper - 1); + } + + /* Returns random (unsorted) partition which is a representation of sum as a sum of integers not less than min_part. */ + template + std::vector partition(int size, T sum, T min_part) { + if (size < 0) + __testlib_fail("random_t::partition: size < 0"); + if (size == 0 && sum != 0) + __testlib_fail("random_t::partition: size == 0 && sum != 0"); + if (min_part * size > sum) + __testlib_fail("random_t::partition: min_part * size > sum"); + if (size == 0 && sum == 0) + return std::vector(); + + T sum_ = sum; + sum -= min_part * size; + + std::vector septums(size); + std::vector d = distinct(size - 1, T(1), T(sum + size - 1)); + for (int i = 0; i + 1 < size; i++) + septums[i + 1] = d[i]; + sort(septums.begin(), septums.end()); + + std::vector result(size); + for (int i = 0; i + 1 < size; i++) + result[i] = septums[i + 1] - septums[i] - 1; + result[size - 1] = sum + size - 1 - septums.back(); + + for (std::size_t i = 0; i < result.size(); i++) + result[i] += min_part; + + T result_sum = 0; + for (std::size_t i = 0; i < result.size(); i++) + result_sum += result[i]; + if (result_sum != sum_) + __testlib_fail("random_t::partition: partition sum is expected to be the given sum"); + + if (*std::min_element(result.begin(), result.end()) < min_part) + __testlib_fail("random_t::partition: partition min is expected to be no less than the given min_part"); + + if (int(result.size()) != size || result.size() != (size_t) size) + __testlib_fail("random_t::partition: partition size is expected to be equal to the given size"); + + return result; + } + + /* Returns random (unsorted) partition which is a representation of sum as a sum of positive integers. */ + template + std::vector partition(int size, T sum) { + return partition(size, sum, T(1)); + } +}; + +const int random_t::lim = 25; +const unsigned long long random_t::multiplier = 0x5DEECE66DLL; +const unsigned long long random_t::addend = 0xBLL; +const unsigned long long random_t::mask = (1LL << 48) - 1; +int random_t::version = -1; + +/* Pattern implementation */ +bool pattern::matches(const std::string &s) const { + return matches(s, 0); +} + +static bool __pattern_isSlash(const std::string &s, size_t pos) { + return s[pos] == '\\'; +} + +#ifdef __GNUC__ +__attribute__((pure)) +#endif +static bool __pattern_isCommandChar(const std::string &s, size_t pos, char value) { + if (pos >= s.length()) + return false; + + int slashes = 0; + + int before = int(pos) - 1; + while (before >= 0 && s[before] == '\\') + before--, slashes++; + + return slashes % 2 == 0 && s[pos] == value; +} + +static char __pattern_getChar(const std::string &s, size_t &pos) { + if (__pattern_isSlash(s, pos)) + pos += 2; + else + pos++; + + return s[pos - 1]; +} + +#ifdef __GNUC__ +__attribute__((pure)) +#endif +static int __pattern_greedyMatch(const std::string &s, size_t pos, const std::vector chars) { + int result = 0; + + while (pos < s.length()) { + char c = s[pos++]; + if (!std::binary_search(chars.begin(), chars.end(), c)) + break; + else + result++; + } + + return result; +} + +std::string pattern::src() const { + return s; +} + +bool pattern::matches(const std::string &s, size_t pos) const { + std::string result; + + if (to > 0) { + int size = __pattern_greedyMatch(s, pos, chars); + if (size < from) + return false; + if (size > to) + size = to; + pos += size; + } + + if (children.size() > 0) { + for (size_t child = 0; child < children.size(); child++) + if (children[child].matches(s, pos)) + return true; + return false; + } else + return pos == s.length(); +} + +std::string pattern::next(random_t &rnd) const { + std::string result; + result.reserve(20); + + if (to == INT_MAX) + __testlib_fail("pattern::next(random_t& rnd): can't process character '*' for generation"); + + if (to > 0) { + int count = rnd.next(to - from + 1) + from; + for (int i = 0; i < count; i++) + result += chars[rnd.next(int(chars.size()))]; + } + + if (children.size() > 0) { + int child = rnd.next(int(children.size())); + result += children[child].next(rnd); + } + + return result; +} + +static void __pattern_scanCounts(const std::string &s, size_t &pos, int &from, int &to) { + if (pos >= s.length()) { + from = to = 1; + return; + } + + if (__pattern_isCommandChar(s, pos, '{')) { + std::vector parts; + std::string part; + + pos++; + + while (pos < s.length() && !__pattern_isCommandChar(s, pos, '}')) { + if (__pattern_isCommandChar(s, pos, ',')) + parts.push_back(part), part = "", pos++; + else + part += __pattern_getChar(s, pos); + } + + if (part != "") + parts.push_back(part); + + if (!__pattern_isCommandChar(s, pos, '}')) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + + pos++; + + if (parts.size() < 1 || parts.size() > 2) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + + std::vector numbers; + + for (size_t i = 0; i < parts.size(); i++) { + if (parts[i].length() == 0) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + int number; + if (std::sscanf(parts[i].c_str(), "%d", &number) != 1) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + numbers.push_back(number); + } + + if (numbers.size() == 1) + from = to = numbers[0]; + else + from = numbers[0], to = numbers[1]; + + if (from > to) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + } else { + if (__pattern_isCommandChar(s, pos, '?')) { + from = 0, to = 1, pos++; + return; + } + + if (__pattern_isCommandChar(s, pos, '*')) { + from = 0, to = INT_MAX, pos++; + return; + } + + if (__pattern_isCommandChar(s, pos, '+')) { + from = 1, to = INT_MAX, pos++; + return; + } + + from = to = 1; + } +} + +static std::vector __pattern_scanCharSet(const std::string &s, size_t &pos) { + if (pos >= s.length()) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + + std::vector result; + + if (__pattern_isCommandChar(s, pos, '[')) { + pos++; + bool negative = __pattern_isCommandChar(s, pos, '^'); + if (negative) + pos++; + + char prev = 0; + + while (pos < s.length() && !__pattern_isCommandChar(s, pos, ']')) { + if (__pattern_isCommandChar(s, pos, '-') && prev != 0) { + pos++; + + if (pos + 1 == s.length() || __pattern_isCommandChar(s, pos, ']')) { + result.push_back(prev); + prev = '-'; + continue; + } + + char next = __pattern_getChar(s, pos); + if (prev > next) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + + for (char c = prev; c != next; c++) + result.push_back(c); + result.push_back(next); + + prev = 0; + } else { + if (prev != 0) + result.push_back(prev); + prev = __pattern_getChar(s, pos); + } + } + + if (prev != 0) + result.push_back(prev); + + if (!__pattern_isCommandChar(s, pos, ']')) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + + pos++; + + if (negative) { + std::sort(result.begin(), result.end()); + std::vector actuals; + for (int code = 0; code < 255; code++) { + char c = char(code); + if (!std::binary_search(result.begin(), result.end(), c)) + actuals.push_back(c); + } + result = actuals; + } + + std::sort(result.begin(), result.end()); + } else + result.push_back(__pattern_getChar(s, pos)); + + return result; +} + +pattern::pattern(std::string s) : s(s), from(0), to(0) { + std::string t; + for (size_t i = 0; i < s.length(); i++) + if (!__pattern_isCommandChar(s, i, ' ')) + t += s[i]; + s = t; + + int opened = 0; + int firstClose = -1; + std::vector seps; + + for (size_t i = 0; i < s.length(); i++) { + if (__pattern_isCommandChar(s, i, '(')) { + opened++; + continue; + } + + if (__pattern_isCommandChar(s, i, ')')) { + opened--; + if (opened == 0 && firstClose == -1) + firstClose = int(i); + continue; + } + + if (opened < 0) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + + if (__pattern_isCommandChar(s, i, '|') && opened == 0) + seps.push_back(int(i)); + } + + if (opened != 0) + __testlib_fail("pattern: Illegal pattern (or part) \"" + s + "\""); + + if (seps.size() == 0 && firstClose + 1 == (int) s.length() + && __pattern_isCommandChar(s, 0, '(') && __pattern_isCommandChar(s, s.length() - 1, ')')) { + children.push_back(pattern(s.substr(1, s.length() - 2))); + } else { + if (seps.size() > 0) { + seps.push_back(int(s.length())); + int last = 0; + + for (size_t i = 0; i < seps.size(); i++) { + children.push_back(pattern(s.substr(last, seps[i] - last))); + last = seps[i] + 1; + } + } else { + size_t pos = 0; + chars = __pattern_scanCharSet(s, pos); + __pattern_scanCounts(s, pos, from, to); + if (pos < s.length()) + children.push_back(pattern(s.substr(pos))); + } + } +} + +/* End of pattern implementation */ + +template +inline bool isEof(C c) { + return c == EOFC; +} + +template +inline bool isEoln(C c) { + return (c == LF || c == CR); +} + +template +inline bool isBlanks(C c) { + return (c == LF || c == CR || c == SPACE || c == TAB); +} + +inline std::string trim(const std::string &s) { + if (s.empty()) + return s; + + int left = 0; + while (left < int(s.length()) && isBlanks(s[left])) + left++; + if (left >= int(s.length())) + return ""; + + int right = int(s.length()) - 1; + while (right >= 0 && isBlanks(s[right])) + right--; + if (right < 0) + return ""; + + return s.substr(left, right - left + 1); +} + +enum TMode { + _input, _output, _answer +}; + +/* Outcomes 6-15 are reserved for future use. */ +enum TResult { + _ok = 0, + _wa = 1, + _pe = 2, + _fail = 3, + _dirt = 4, + _points = 5, + _unexpected_eof = 8, + _partially = 16 +}; + +enum TTestlibMode { + _unknown, _checker, _validator, _generator, _interactor, _scorer +}; + +#define _pc(exitCode) (TResult(_partially + (exitCode))) + +/* Outcomes 6-15 are reserved for future use. */ +const std::string outcomes[] = { + "accepted", + "wrong-answer", + "presentation-error", + "fail", + "fail", +#ifndef PCMS2 + "points", +#else + "relative-scoring", +#endif + "reserved", + "reserved", + "unexpected-eof", + "reserved", + "reserved", + "reserved", + "reserved", + "reserved", + "reserved", + "reserved", + "partially-correct" +}; + +class InputStreamReader { +public: + virtual void setTestCase(int testCase) = 0; + + virtual std::vector getReadChars() = 0; + + virtual int curChar() = 0; + + virtual int nextChar() = 0; + + virtual void skipChar() = 0; + + virtual void unreadChar(int c) = 0; + + virtual std::string getName() = 0; + + virtual bool eof() = 0; + + virtual void close() = 0; + + virtual int getLine() = 0; + + virtual ~InputStreamReader() = 0; +}; + +InputStreamReader::~InputStreamReader() { + // No operations. +} + +class StringInputStreamReader : public InputStreamReader { +private: + std::string s; + size_t pos; + +public: + StringInputStreamReader(const std::string &content) : s(content), pos(0) { + // No operations. + } + + void setTestCase(int) { + __testlib_fail("setTestCase not implemented in StringInputStreamReader"); + } + + std::vector getReadChars() { + __testlib_fail("getReadChars not implemented in StringInputStreamReader"); + } + + int curChar() { + if (pos >= s.length()) + return EOFC; + else + return s[pos]; + } + + int nextChar() { + if (pos >= s.length()) { + pos++; + return EOFC; + } else + return s[pos++]; + } + + void skipChar() { + pos++; + } + + void unreadChar(int c) { + if (pos == 0) + __testlib_fail("StringInputStreamReader::unreadChar(int): pos == 0."); + pos--; + if (pos < s.length()) + s[pos] = char(c); + } + + std::string getName() { + return __testlib_part(s); + } + + int getLine() { + return -1; + } + + bool eof() { + return pos >= s.length(); + } + + void close() { + // No operations. + } +}; + +class FileInputStreamReader : public InputStreamReader { +private: + std::FILE *file; + std::string name; + int line; + std::vector undoChars; + std::vector readChars; + std::vector undoReadChars; + + inline int postprocessGetc(int getcResult) { + if (getcResult != EOF) + return getcResult; + else + return EOFC; + } + + int getc(FILE *file) { + int c; + int rc; + + if (undoChars.empty()) { + c = rc = ::getc(file); + } else { + c = undoChars.back(); + undoChars.pop_back(); + rc = undoReadChars.back(); + undoReadChars.pop_back(); + } + + if (c == LF) + line++; + + readChars.push_back(rc); + return c; + } + + int ungetc(int c/*, FILE* file*/) { + if (!readChars.empty()) { + undoReadChars.push_back(readChars.back()); + readChars.pop_back(); + } + if (c == LF) + line--; + undoChars.push_back(c); + return c; + } + +public: + FileInputStreamReader(std::FILE *file, const std::string &name) : file(file), name(name), line(1) { + // No operations. + } + + void setTestCase(int testCase) { + if (testCase < 0 || testCase > __TESTLIB_MAX_TEST_CASE) + __testlib_fail(format("testCase expected fit in [1,%d], but %d doesn't", __TESTLIB_MAX_TEST_CASE, testCase)); + readChars.push_back(testCase + 256); + } + + std::vector getReadChars() { + return readChars; + } + + int curChar() { + if (feof(file)) + return EOFC; + else { + int c = getc(file); + ungetc(c/*, file*/); + return postprocessGetc(c); + } + } + + int nextChar() { + if (feof(file)) + return EOFC; + else + return postprocessGetc(getc(file)); + } + + void skipChar() { + getc(file); + } + + void unreadChar(int c) { + ungetc(c/*, file*/); + } + + std::string getName() { + return name; + } + + int getLine() { + return line; + } + + bool eof() { + if (NULL == file || feof(file)) + return true; + else { + int c = nextChar(); + if (c == EOFC || (c == EOF && feof(file))) + return true; + unreadChar(c); + return false; + } + } + + void close() { + if (NULL != file) { + fclose(file); + file = NULL; + } + } +}; + +class BufferedFileInputStreamReader : public InputStreamReader { +private: + static const size_t BUFFER_SIZE; + static const size_t MAX_UNREAD_COUNT; + + std::FILE *file; + std::string name; + int line; + + char *buffer; + bool *isEof; + int bufferPos; + size_t bufferSize; + + bool refill() { + if (NULL == file) + __testlib_fail("BufferedFileInputStreamReader: file == NULL (" + getName() + ")"); + + if (bufferPos >= int(bufferSize)) { + size_t readSize = fread( + buffer + MAX_UNREAD_COUNT, + 1, + BUFFER_SIZE - MAX_UNREAD_COUNT, + file + ); + + if (readSize < BUFFER_SIZE - MAX_UNREAD_COUNT + && ferror(file)) + __testlib_fail("BufferedFileInputStreamReader: unable to read (" + getName() + ")"); + + bufferSize = MAX_UNREAD_COUNT + readSize; + bufferPos = int(MAX_UNREAD_COUNT); + std::memset(isEof + MAX_UNREAD_COUNT, 0, sizeof(isEof[0]) * readSize); + + return readSize > 0; + } else + return true; + } + + char increment() { + char c; + if ((c = buffer[bufferPos++]) == LF) + line++; + return c; + } + +public: + BufferedFileInputStreamReader(std::FILE *file, const std::string &name) : file(file), name(name), line(1) { + buffer = new char[BUFFER_SIZE]; + isEof = new bool[BUFFER_SIZE]; + bufferSize = MAX_UNREAD_COUNT; + bufferPos = int(MAX_UNREAD_COUNT); + } + + ~BufferedFileInputStreamReader() { + if (NULL != buffer) { + delete[] buffer; + buffer = NULL; + } + if (NULL != isEof) { + delete[] isEof; + isEof = NULL; + } + } + + void setTestCase(int) { + __testlib_fail("setTestCase not implemented in BufferedFileInputStreamReader"); + } + + std::vector getReadChars() { + __testlib_fail("getReadChars not implemented in BufferedFileInputStreamReader"); + } + + int curChar() { + if (!refill()) + return EOFC; + + return isEof[bufferPos] ? EOFC : buffer[bufferPos]; + } + + int nextChar() { + if (!refill()) + return EOFC; + + return isEof[bufferPos] ? EOFC : increment(); + } + + void skipChar() { + increment(); + } + + void unreadChar(int c) { + bufferPos--; + if (bufferPos < 0) + __testlib_fail("BufferedFileInputStreamReader::unreadChar(int): bufferPos < 0"); + isEof[bufferPos] = (c == EOFC); + buffer[bufferPos] = char(c); + if (c == LF) + line--; + } + + std::string getName() { + return name; + } + + int getLine() { + return line; + } + + bool eof() { + return !refill() || EOFC == curChar(); + } + + void close() { + if (NULL != file) { + fclose(file); + file = NULL; + } + } +}; + +const size_t BufferedFileInputStreamReader::BUFFER_SIZE = 2000000; +const size_t BufferedFileInputStreamReader::MAX_UNREAD_COUNT = BufferedFileInputStreamReader::BUFFER_SIZE / 2; + +/* + * Streams to be used for reading data in checkers or validators. + * Each read*() method moves pointer to the next character after the + * read value. + */ +struct InStream { + /* Do not use them. */ + InStream(); + + ~InStream(); + + /* Wrap std::string with InStream. */ + InStream(const InStream &baseStream, std::string content); + + InputStreamReader *reader; + int lastLine; + + std::string name; + TMode mode; + bool opened; + bool stdfile; + bool strict; + + int wordReserveSize; + std::string _tmpReadToken; + + int readManyIteration; + size_t maxFileSize; + size_t maxTokenLength; + size_t maxMessageLength; + + void init(std::string fileName, TMode mode); + + void init(std::FILE *f, TMode mode); + + void setTestCase(int testCase); + std::vector getReadChars(); + + /* Moves stream pointer to the first non-white-space character or EOF. */ + void skipBlanks(); + + /* Returns current character in the stream. Doesn't remove it from stream. */ + char curChar(); + + /* Moves stream pointer one character forward. */ + void skipChar(); + + /* Returns current character and moves pointer one character forward. */ + char nextChar(); + + /* Returns current character and moves pointer one character forward. */ + char readChar(); + + /* As "readChar()" but ensures that the result is equal to given parameter. */ + char readChar(char c); + + /* As "readChar()" but ensures that the result is equal to the space (code=32). */ + char readSpace(); + + /* Puts back the character into the stream. */ + void unreadChar(char c); + + /* Reopens stream, you should not use it. */ + void reset(std::FILE *file = NULL); + + /* Checks that current position is EOF. If not it doesn't move stream pointer. */ + bool eof(); + + /* Moves pointer to the first non-white-space character and calls "eof()". */ + bool seekEof(); + + /* + * Checks that current position contains EOLN. + * If not it doesn't move stream pointer. + * In strict mode expects "#13#10" for windows or "#10" for other platforms. + */ + bool eoln(); + + /* Moves pointer to the first non-space and non-tab character and calls "eoln()". */ + bool seekEoln(); + + /* Moves stream pointer to the first character of the next line (if exists). */ + void nextLine(); + + /* + * Reads new token. Ignores white-spaces into the non-strict mode + * (strict mode is used in validators usually). + */ + std::string readWord(); + + /* The same as "readWord()", it is preffered to use "readToken()". */ + std::string readToken(); + + /* The same as "readWord()", but ensures that token matches to given pattern. */ + std::string readWord(const std::string &ptrn, const std::string &variableName = ""); + + std::string readWord(const pattern &p, const std::string &variableName = ""); + + std::vector + readWords(int size, const std::string &ptrn, const std::string &variablesName = "", int indexBase = 1); + + std::vector + readWords(int size, const pattern &p, const std::string &variablesName = "", int indexBase = 1); + + std::vector readWords(int size, int indexBase = 1); + + /* The same as "readToken()", but ensures that token matches to given pattern. */ + std::string readToken(const std::string &ptrn, const std::string &variableName = ""); + + std::string readToken(const pattern &p, const std::string &variableName = ""); + + std::vector + readTokens(int size, const std::string &ptrn, const std::string &variablesName = "", int indexBase = 1); + + std::vector + readTokens(int size, const pattern &p, const std::string &variablesName = "", int indexBase = 1); + + std::vector readTokens(int size, int indexBase = 1); + + void readWordTo(std::string &result); + + void readWordTo(std::string &result, const pattern &p, const std::string &variableName = ""); + + void readWordTo(std::string &result, const std::string &ptrn, const std::string &variableName = ""); + + void readTokenTo(std::string &result); + + void readTokenTo(std::string &result, const pattern &p, const std::string &variableName = ""); + + void readTokenTo(std::string &result, const std::string &ptrn, const std::string &variableName = ""); + + /* + * Reads new long long value. Ignores white-spaces into the non-strict mode + * (strict mode is used in validators usually). + */ + long long readLong(); + + unsigned long long readUnsignedLong(); + + /* + * Reads new int. Ignores white-spaces into the non-strict mode + * (strict mode is used in validators usually). + */ + int readInteger(); + + /* + * Reads new int. Ignores white-spaces into the non-strict mode + * (strict mode is used in validators usually). + */ + int readInt(); + + /* As "readLong()" but ensures that value in the range [minv,maxv]. */ + long long readLong(long long minv, long long maxv, const std::string &variableName = ""); + + /* Reads space-separated sequence of long longs. */ + std::vector + readLongs(int size, long long minv, long long maxv, const std::string &variablesName = "", int indexBase = 1); + + /* Reads space-separated sequence of long longs. */ + std::vector readLongs(int size, int indexBase = 1); + + unsigned long long + readUnsignedLong(unsigned long long minv, unsigned long long maxv, const std::string &variableName = ""); + + std::vector + readUnsignedLongs(int size, unsigned long long minv, unsigned long long maxv, const std::string &variablesName = "", + int indexBase = 1); + + std::vector readUnsignedLongs(int size, int indexBase = 1); + + unsigned long long readLong(unsigned long long minv, unsigned long long maxv, const std::string &variableName = ""); + + std::vector + readLongs(int size, unsigned long long minv, unsigned long long maxv, const std::string &variablesName = "", + int indexBase = 1); + + /* As "readInteger()" but ensures that value in the range [minv,maxv]. */ + int readInteger(int minv, int maxv, const std::string &variableName = ""); + + /* As "readInt()" but ensures that value in the range [minv,maxv]. */ + int readInt(int minv, int maxv, const std::string &variableName = ""); + + /* Reads space-separated sequence of integers. */ + std::vector + readIntegers(int size, int minv, int maxv, const std::string &variablesName = "", int indexBase = 1); + + /* Reads space-separated sequence of integers. */ + std::vector readIntegers(int size, int indexBase = 1); + + /* Reads space-separated sequence of integers. */ + std::vector readInts(int size, int minv, int maxv, const std::string &variablesName = "", int indexBase = 1); + + /* Reads space-separated sequence of integers. */ + std::vector readInts(int size, int indexBase = 1); + + /* + * Reads new double. Ignores white-spaces into the non-strict mode + * (strict mode is used in validators usually). + */ + double readReal(); + + /* + * Reads new double. Ignores white-spaces into the non-strict mode + * (strict mode is used in validators usually). + */ + double readDouble(); + + /* As "readReal()" but ensures that value in the range [minv,maxv]. */ + double readReal(double minv, double maxv, const std::string &variableName = ""); + + std::vector + readReals(int size, double minv, double maxv, const std::string &variablesName = "", int indexBase = 1); + + std::vector readReals(int size, int indexBase = 1); + + /* As "readDouble()" but ensures that value in the range [minv,maxv]. */ + double readDouble(double minv, double maxv, const std::string &variableName = ""); + + std::vector + readDoubles(int size, double minv, double maxv, const std::string &variablesName = "", int indexBase = 1); + + std::vector readDoubles(int size, int indexBase = 1); + + /* + * As "readReal()" but ensures that value in the range [minv,maxv] and + * number of digit after the decimal point is in range [minAfterPointDigitCount,maxAfterPointDigitCount] + * and number is in the form "[-]digit(s)[.digit(s)]". + */ + double readStrictReal(double minv, double maxv, + int minAfterPointDigitCount, int maxAfterPointDigitCount, + const std::string &variableName = ""); + + std::vector readStrictReals(int size, double minv, double maxv, + int minAfterPointDigitCount, int maxAfterPointDigitCount, + const std::string &variablesName = "", int indexBase = 1); + + /* + * As "readDouble()" but ensures that value in the range [minv,maxv] and + * number of digit after the decimal point is in range [minAfterPointDigitCount,maxAfterPointDigitCount] + * and number is in the form "[-]digit(s)[.digit(s)]". + */ + double readStrictDouble(double minv, double maxv, + int minAfterPointDigitCount, int maxAfterPointDigitCount, + const std::string &variableName = ""); + + std::vector readStrictDoubles(int size, double minv, double maxv, + int minAfterPointDigitCount, int maxAfterPointDigitCount, + const std::string &variablesName = "", int indexBase = 1); + + /* As readLine(). */ + std::string readString(); + + /* Read many lines. */ + std::vector readStrings(int size, int indexBase = 1); + + /* See readLine(). */ + void readStringTo(std::string &result); + + /* The same as "readLine()/readString()", but ensures that line matches to the given pattern. */ + std::string readString(const pattern &p, const std::string &variableName = ""); + + /* The same as "readLine()/readString()", but ensures that line matches to the given pattern. */ + std::string readString(const std::string &ptrn, const std::string &variableName = ""); + + /* Read many lines. */ + std::vector + readStrings(int size, const pattern &p, const std::string &variableName = "", int indexBase = 1); + + /* Read many lines. */ + std::vector + readStrings(int size, const std::string &ptrn, const std::string &variableName = "", int indexBase = 1); + + /* The same as "readLine()/readString()", but ensures that line matches to the given pattern. */ + void readStringTo(std::string &result, const pattern &p, const std::string &variableName = ""); + + /* The same as "readLine()/readString()", but ensures that line matches to the given pattern. */ + void readStringTo(std::string &result, const std::string &ptrn, const std::string &variableName = ""); + + /* + * Reads line from the current position to EOLN or EOF. Moves stream pointer to + * the first character of the new line (if possible). + */ + std::string readLine(); + + /* Read many lines. */ + std::vector readLines(int size, int indexBase = 1); + + /* See readLine(). */ + void readLineTo(std::string &result); + + /* The same as "readLine()", but ensures that line matches to the given pattern. */ + std::string readLine(const pattern &p, const std::string &variableName = ""); + + /* The same as "readLine()", but ensures that line matches to the given pattern. */ + std::string readLine(const std::string &ptrn, const std::string &variableName = ""); + + /* Read many lines. */ + std::vector + readLines(int size, const pattern &p, const std::string &variableName = "", int indexBase = 1); + + /* Read many lines. */ + std::vector + readLines(int size, const std::string &ptrn, const std::string &variableName = "", int indexBase = 1); + + /* The same as "readLine()", but ensures that line matches to the given pattern. */ + void readLineTo(std::string &result, const pattern &p, const std::string &variableName = ""); + + /* The same as "readLine()", but ensures that line matches to the given pattern. */ + void readLineTo(std::string &result, const std::string &ptrn, const std::string &variableName = ""); + + /* Reads EOLN or fails. Use it in validators. Calls "eoln()" method internally. */ + void readEoln(); + + /* Reads EOF or fails. Use it in validators. Calls "eof()" method internally. */ + void readEof(); + + /* + * Quit-functions aborts program with and : + * input/answer streams replace any result to FAIL. + */ + NORETURN void quit(TResult result, const char *msg); + /* + * Quit-functions aborts program with and : + * input/answer streams replace any result to FAIL. + */ + NORETURN void quitf(TResult result, const char *msg, ...); + + /* + * Quit-functions aborts program with and : + * input/answer streams replace any result to FAIL. + */ + void quitif(bool condition, TResult result, const char *msg, ...); + /* + * Quit-functions aborts program with and : + * input/answer streams replace any result to FAIL. + */ + NORETURN void quits(TResult result, std::string msg); + + /* + * Checks condition and aborts a program if codition is false. + * Returns _wa for ouf and _fail on any other streams. + */ +#ifdef __GNUC__ + __attribute__ ((format (printf, 3, 4))) +#endif + void ensuref(bool cond, const char *format, ...); + + void __testlib_ensure(bool cond, std::string message); + + void close(); + + const static int NO_INDEX = INT_MAX; + const static char OPEN_BRACKET = char(11); + const static char CLOSE_BRACKET = char(17); + + const static WORD LightGray = 0x07; + const static WORD LightRed = 0x0c; + const static WORD LightCyan = 0x0b; + const static WORD LightGreen = 0x0a; + const static WORD LightYellow = 0x0e; + + static void textColor(WORD color); + + static void quitscr(WORD color, const char *msg); + + static void quitscrS(WORD color, std::string msg); + + void xmlSafeWrite(std::FILE *file, const char *msg); + + /* Skips UTF-8 Byte Order Mark. */ + void skipBom(); + +private: + InStream(const InStream &); + + InStream &operator=(const InStream &); +}; + +InStream inf; +InStream ouf; +InStream ans; +bool appesMode; +std::string resultName; +std::string checkerName = "untitled checker"; +random_t rnd; +TTestlibMode testlibMode = _unknown; +double __testlib_points = std::numeric_limits::infinity(); + +struct ValidatorBoundsHit { + static const double EPS; + bool minHit; + bool maxHit; + + ValidatorBoundsHit(bool minHit = false, bool maxHit = false) : minHit(minHit), maxHit(maxHit) { + }; + + ValidatorBoundsHit merge(const ValidatorBoundsHit &validatorBoundsHit) { + return ValidatorBoundsHit( + __testlib_max(minHit, validatorBoundsHit.minHit), + __testlib_max(maxHit, validatorBoundsHit.maxHit) + ); + } +}; + +const double ValidatorBoundsHit::EPS = 1E-12; + +class Validator { +private: + const static std::string TEST_MARKUP_HEADER; + const static std::string TEST_CASE_OPEN_TAG; + const static std::string TEST_CASE_CLOSE_TAG; + + bool _initialized; + std::string _testset; + std::string _group; + + std::string _testOverviewLogFileName; + std::string _testMarkupFileName; + int _testCase = -1; + std::string _testCaseFileName; + + std::map _boundsHitByVariableName; + std::set _features; + std::set _hitFeatures; + + bool isVariableNameBoundsAnalyzable(const std::string &variableName) { + for (size_t i = 0; i < variableName.length(); i++) + if ((variableName[i] >= '0' && variableName[i] <= '9') || variableName[i] < ' ') + return false; + return true; + } + + bool isFeatureNameAnalyzable(const std::string &featureName) { + for (size_t i = 0; i < featureName.length(); i++) + if (featureName[i] < ' ') + return false; + return true; + } + +public: + Validator() : _initialized(false), _testset("tests"), _group() { + } + + void initialize() { + _initialized = true; + } + + std::string testset() const { + if (!_initialized) + __testlib_fail("Validator should be initialized with registerValidation(argc, argv) instead of registerValidation() to support validator.testset()"); + return _testset; + } + + std::string group() const { + if (!_initialized) + __testlib_fail("Validator should be initialized with registerValidation(argc, argv) instead of registerValidation() to support validator.group()"); + return _group; + } + + std::string testOverviewLogFileName() const { + return _testOverviewLogFileName; + } + + std::string testMarkupFileName() const { + return _testMarkupFileName; + } + + int testCase() const { + return _testCase; + } + + std::string testCaseFileName() const { + return _testCaseFileName; + } + + void setTestset(const char *const testset) { + _testset = testset; + } + + void setGroup(const char *const group) { + _group = group; + } + + void setTestOverviewLogFileName(const char *const testOverviewLogFileName) { + _testOverviewLogFileName = testOverviewLogFileName; + } + + void setTestMarkupFileName(const char *const testMarkupFileName) { + _testMarkupFileName = testMarkupFileName; + } + + void setTestCase(int testCase) { + _testCase = testCase; + } + + void setTestCaseFileName(const char *const testCaseFileName) { + _testCaseFileName = testCaseFileName; + } + + void addBoundsHit(const std::string &variableName, ValidatorBoundsHit boundsHit) { + if (isVariableNameBoundsAnalyzable(variableName)) { + _boundsHitByVariableName[variableName] + = boundsHit.merge(_boundsHitByVariableName[variableName]); + } + } + + std::string getBoundsHitLog() { + std::string result; + for (std::map::iterator i = _boundsHitByVariableName.begin(); + i != _boundsHitByVariableName.end(); + i++) { + result += "\"" + i->first + "\":"; + if (i->second.minHit) + result += " min-value-hit"; + if (i->second.maxHit) + result += " max-value-hit"; + result += "\n"; + } + return result; + } + + std::string getFeaturesLog() { + std::string result; + for (std::set::iterator i = _features.begin(); + i != _features.end(); + i++) { + result += "feature \"" + *i + "\":"; + if (_hitFeatures.count(*i)) + result += " hit"; + result += "\n"; + } + return result; + } + + void writeTestOverviewLog() { + if (!_testOverviewLogFileName.empty()) { + std::string fileName(_testOverviewLogFileName); + _testOverviewLogFileName = ""; + FILE *testOverviewLogFile = fopen(fileName.c_str(), "w"); + if (NULL == testOverviewLogFile) + __testlib_fail("Validator::writeTestOverviewLog: can't write test overview log to (" + fileName + ")"); + fprintf(testOverviewLogFile, "%s%s", getBoundsHitLog().c_str(), getFeaturesLog().c_str()); + if (fclose(testOverviewLogFile)) + __testlib_fail( + "Validator::writeTestOverviewLog: can't close test overview log file (" + fileName + ")"); + } + } + + void writeTestMarkup() { + if (!_testMarkupFileName.empty()) { + std::vector readChars = inf.getReadChars(); + if (!readChars.empty()) { + std::string markup(TEST_MARKUP_HEADER); + for (size_t i = 0; i < readChars.size(); i++) { + int c = readChars[i]; + if (i + 1 == readChars.size() && c == -1) + continue; + if (c <= 256) { + char cc = char(c); + if (cc == '\\' || cc == '!') + markup += '\\'; + markup += cc; + } else { + markup += TEST_CASE_OPEN_TAG; + markup += toString(c - 256); + markup += TEST_CASE_CLOSE_TAG; + } + } + FILE* f; + bool standard_file = false; + if (_testMarkupFileName == "stdout") + f = stdout, standard_file = true; + else if (_testMarkupFileName == "stderr") + f = stderr, standard_file = true; + else { + f = fopen(_testMarkupFileName.c_str(), "wb"); + if (NULL == f) + __testlib_fail("Validator::writeTestMarkup: can't write test markup to (" + _testMarkupFileName + ")"); + } + std::fprintf(f, "%s", markup.c_str()); + std::fflush(f); + if (!standard_file) + if (std::fclose(f)) + __testlib_fail("Validator::writeTestMarkup: can't close test markup file (" + _testCaseFileName + ")"); + } + } + } + + void writeTestCase() { + if (_testCase > 0) { + std::vector readChars = inf.getReadChars(); + if (!readChars.empty()) { + std::string content, testCaseContent; + bool matchedTestCase = false; + for (size_t i = 0; i < readChars.size(); i++) { + int c = readChars[i]; + if (i + 1 == readChars.size() && c == -1) + continue; + if (c <= 256) + content += char(c); + else { + if (matchedTestCase) { + testCaseContent = content; + matchedTestCase = false; + } + content = ""; + int testCase = c - 256; + if (testCase == _testCase) + matchedTestCase = true; + } + } + if (matchedTestCase) + testCaseContent = content; + + if (!testCaseContent.empty()) { + FILE* f; + bool standard_file = false; + if (_testCaseFileName.empty() || _testCaseFileName == "stdout") + f = stdout, standard_file = true; + else if (_testCaseFileName == "stderr") + f = stderr, standard_file = true; + else { + f = fopen(_testCaseFileName.c_str(), "wb"); + if (NULL == f) + __testlib_fail("Validator::writeTestCase: can't write test case to (" + _testCaseFileName + ")"); + } + std::fprintf(f, "%s", testCaseContent.c_str()); + std::fflush(f); + if (!standard_file) + if (std::fclose(f)) + __testlib_fail("Validator::writeTestCase: can't close test case file (" + _testCaseFileName + ")"); + } + } + } + } + + void addFeature(const std::string &feature) { + if (_features.count(feature)) + __testlib_fail("Feature " + feature + " registered twice."); + if (!isFeatureNameAnalyzable(feature)) + __testlib_fail("Feature name '" + feature + "' contains restricted characters."); + + _features.insert(feature); + } + + void feature(const std::string &feature) { + if (!isFeatureNameAnalyzable(feature)) + __testlib_fail("Feature name '" + feature + "' contains restricted characters."); + + if (!_features.count(feature)) + __testlib_fail("Feature " + feature + " didn't registered via addFeature(feature)."); + + _hitFeatures.insert(feature); + } +} validator; + +const std::string Validator::TEST_MARKUP_HEADER = "MU\xF3\x01"; +const std::string Validator::TEST_CASE_OPEN_TAG = "!c"; +const std::string Validator::TEST_CASE_CLOSE_TAG = ";"; + +struct TestlibFinalizeGuard { + static bool alive; + static bool registered; + + int quitCount, readEofCount; + + TestlibFinalizeGuard() : quitCount(0), readEofCount(0) { + // No operations. + } + + ~TestlibFinalizeGuard() { + bool _alive = alive; + alive = false; + + if (_alive) { + if (testlibMode == _checker && quitCount == 0) + __testlib_fail("Checker must end with quit or quitf call."); + + if (testlibMode == _validator && readEofCount == 0 && quitCount == 0) + __testlib_fail("Validator must end with readEof call."); + + /* opts */ + autoEnsureNoUnusedOpts(); + + if (!registered) + __testlib_fail("Call register-function in the first line of the main (registerTestlibCmd or other similar)"); + } + + if (__testlib_exitCode == 0) { + validator.writeTestOverviewLog(); + validator.writeTestMarkup(); + validator.writeTestCase(); + } + } + +private: + /* opts */ + void autoEnsureNoUnusedOpts(); +}; + +bool TestlibFinalizeGuard::alive = true; +bool TestlibFinalizeGuard::registered = false; +extern TestlibFinalizeGuard testlibFinalizeGuard; + +/* + * Call it to disable checks on finalization. + */ +void disableFinalizeGuard() { + TestlibFinalizeGuard::alive = false; +} + +/* Interactor streams. + */ +std::fstream tout; + +/* implementation + */ + +InStream::InStream() { + reader = NULL; + lastLine = -1; + opened = false; + name = ""; + mode = _input; + strict = false; + stdfile = false; + wordReserveSize = 4; + readManyIteration = NO_INDEX; + maxFileSize = 128 * 1024 * 1024; // 128MB. + maxTokenLength = 32 * 1024 * 1024; // 32MB. + maxMessageLength = 32000; +} + +InStream::InStream(const InStream &baseStream, std::string content) { + reader = new StringInputStreamReader(content); + lastLine = -1; + opened = true; + strict = baseStream.strict; + stdfile = false; + mode = baseStream.mode; + name = "based on " + baseStream.name; + readManyIteration = NO_INDEX; + maxFileSize = 128 * 1024 * 1024; // 128MB. + maxTokenLength = 32 * 1024 * 1024; // 32MB. + maxMessageLength = 32000; +} + +InStream::~InStream() { + if (NULL != reader) { + reader->close(); + delete reader; + reader = NULL; + } +} + +void InStream::setTestCase(int testCase) { + if (testlibMode != _validator || mode != _input || !stdfile || this != &inf) + __testlib_fail("InStream::setTestCase can be used only for inf in validator-mode." + " Actually, prefer setTestCase function instead of InStream member"); + reader->setTestCase(testCase); +} + +std::vector InStream::getReadChars() { + if (testlibMode != _validator || mode != _input || !stdfile || this != &inf) + __testlib_fail("InStream::getReadChars can be used only for inf in validator-mode."); + return reader == NULL ? std::vector() : reader->getReadChars(); +} + +void setTestCase(int testCase) { + static bool first_run = true; + static bool zero_based = false; + + if (first_run && testCase == 0) + zero_based = true; + + if (zero_based) + testCase++; + + __testlib_hasTestCase = true; + __testlib_testCase = testCase; + + if (testlibMode == _validator) + inf.setTestCase(testCase); + + first_run = false; +} + +#ifdef __GNUC__ +__attribute__((const)) +#endif +int resultExitCode(TResult r) { + if (r == _ok) + return OK_EXIT_CODE; + if (r == _wa) + return WA_EXIT_CODE; + if (r == _pe) + return PE_EXIT_CODE; + if (r == _fail) + return FAIL_EXIT_CODE; + if (r == _dirt) + return DIRT_EXIT_CODE; + if (r == _points) + return POINTS_EXIT_CODE; + if (r == _unexpected_eof) +#ifdef ENABLE_UNEXPECTED_EOF + return UNEXPECTED_EOF_EXIT_CODE; +#else + return PE_EXIT_CODE; +#endif + if (r >= _partially) + return PC_BASE_EXIT_CODE + (r - _partially); + return FAIL_EXIT_CODE; +} + +void InStream::textColor( +#if !(defined(ON_WINDOWS) && (!defined(_MSC_VER) || _MSC_VER > 1400)) && defined(__GNUC__) + __attribute__((unused)) +#endif + WORD color +) { +#if defined(ON_WINDOWS) && (!defined(_MSC_VER) || _MSC_VER > 1400) + HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(handle, color); +#endif +#if !defined(ON_WINDOWS) && defined(__GNUC__) + if (isatty(2)) + { + switch (color) + { + case LightRed: + fprintf(stderr, "\033[1;31m"); + break; + case LightCyan: + fprintf(stderr, "\033[1;36m"); + break; + case LightGreen: + fprintf(stderr, "\033[1;32m"); + break; + case LightYellow: + fprintf(stderr, "\033[1;33m"); + break; + case LightGray: + default: + fprintf(stderr, "\033[0m"); + } + } +#endif +} + +#ifdef TESTLIB_THROW_EXIT_EXCEPTION_INSTEAD_OF_EXIT +class exit_exception: public std::exception { +private: + int exitCode; +public: + exit_exception(int exitCode): exitCode(exitCode) {} + int getExitCode() { return exitCode; } +}; +#endif + +NORETURN void halt(int exitCode) { +#ifdef FOOTER + InStream::textColor(InStream::LightGray); + std::fprintf(stderr, "Checker: \"%s\"\n", checkerName.c_str()); + std::fprintf(stderr, "Exit code: %d\n", exitCode); + InStream::textColor(InStream::LightGray); +#endif + __testlib_exitCode = exitCode; +#ifdef TESTLIB_THROW_EXIT_EXCEPTION_INSTEAD_OF_EXIT + throw exit_exception(exitCode); +#endif + std::exit(exitCode); +} + +static bool __testlib_shouldCheckDirt(TResult result) { + return result == _ok || result == _points || result >= _partially; +} + +static std::string __testlib_appendMessage(const std::string &message, const std::string &extra) { + int openPos = -1, closePos = -1; + for (size_t i = 0; i < message.length(); i++) { + if (message[i] == InStream::OPEN_BRACKET) { + if (openPos == -1) + openPos = int(i); + else + openPos = INT_MAX; + } + if (message[i] == InStream::CLOSE_BRACKET) { + if (closePos == -1) + closePos = int(i); + else + closePos = INT_MAX; + } + } + if (openPos != -1 && openPos != INT_MAX + && closePos != -1 && closePos != INT_MAX + && openPos < closePos) { + size_t index = message.find(extra, openPos); + if (index == std::string::npos || int(index) >= closePos) { + std::string result(message); + result.insert(closePos, ", " + extra); + return result; + } + return message; + } + + return message + " " + InStream::OPEN_BRACKET + extra + InStream::CLOSE_BRACKET; +} + +static std::string __testlib_toPrintableMessage(const std::string &message) { + int openPos = -1, closePos = -1; + for (size_t i = 0; i < message.length(); i++) { + if (message[i] == InStream::OPEN_BRACKET) { + if (openPos == -1) + openPos = int(i); + else + openPos = INT_MAX; + } + if (message[i] == InStream::CLOSE_BRACKET) { + if (closePos == -1) + closePos = int(i); + else + closePos = INT_MAX; + } + } + if (openPos != -1 && openPos != INT_MAX + && closePos != -1 && closePos != INT_MAX + && openPos < closePos) { + std::string result(message); + result[openPos] = '('; + result[closePos] = ')'; + return result; + } + + return message; +} + +NORETURN void InStream::quit(TResult result, const char *msg) { + if (TestlibFinalizeGuard::alive) + testlibFinalizeGuard.quitCount++; + + std::string message(msg); + message = trim(message); + + if (__testlib_hasTestCase) { + if (result != _ok) + message = __testlib_appendMessage(message, "test case " + vtos(__testlib_testCase)); + else { + if (__testlib_testCase == 1) + message = __testlib_appendMessage(message, vtos(__testlib_testCase) + " test case"); + else + message = __testlib_appendMessage(message, vtos(__testlib_testCase) + " test cases"); + } + } + + // You can change maxMessageLength. + // Example: 'inf.maxMessageLength = 1024 * 1024;'. + if (message.length() > maxMessageLength) { + std::string warn = "message length exceeds " + vtos(maxMessageLength) + + ", the message is truncated: "; + message = warn + message.substr(0, maxMessageLength - warn.length()); + } + +#ifndef ENABLE_UNEXPECTED_EOF + if (result == _unexpected_eof) + result = _pe; +#endif + + if (testlibMode == _scorer && result != _fail) + quits(_fail, "Scorer should return points only. Don't use a quit function."); + + if (mode != _output && result != _fail) { + if (mode == _input && testlibMode == _validator && lastLine != -1) + quits(_fail, __testlib_appendMessage(__testlib_appendMessage(message, name), "line " + vtos(lastLine))); + else + quits(_fail, __testlib_appendMessage(message, name)); + } + + std::FILE *resultFile; + std::string errorName; + + if (__testlib_shouldCheckDirt(result)) { + if (testlibMode != _interactor && !ouf.seekEof()) + quit(_dirt, "Extra information in the output file"); + } + + int pctype = result - _partially; + bool isPartial = false; + + switch (result) { + case _ok: + errorName = "ok "; + quitscrS(LightGreen, errorName); + break; + case _wa: + errorName = "wrong answer "; + quitscrS(LightRed, errorName); + break; + case _pe: + errorName = "wrong output format "; + quitscrS(LightRed, errorName); + break; + case _fail: + errorName = "FAIL "; + quitscrS(LightRed, errorName); + break; + case _dirt: + errorName = "wrong output format "; + quitscrS(LightCyan, errorName); + result = _pe; + break; + case _points: + errorName = "points "; + quitscrS(LightYellow, errorName); + break; + case _unexpected_eof: + errorName = "unexpected eof "; + quitscrS(LightCyan, errorName); + break; + default: + if (result >= _partially) { + errorName = format("partially correct (%d) ", pctype); + isPartial = true; + quitscrS(LightYellow, errorName); + } else + quit(_fail, "What is the code ??? "); + } + + if (resultName != "") { + resultFile = std::fopen(resultName.c_str(), "w"); + if (resultFile == NULL) { + resultName = ""; + quit(_fail, "Can not write to the result file"); + } + if (appesMode) { + std::fprintf(resultFile, ""); + if (isPartial) + std::fprintf(resultFile, "", + outcomes[(int) _partially].c_str(), pctype); + else { + if (result != _points) + std::fprintf(resultFile, "", outcomes[(int) result].c_str()); + else { + if (__testlib_points == std::numeric_limits::infinity()) + quit(_fail, "Expected points, but infinity found"); + std::string stringPoints = removeDoubleTrailingZeroes(format("%.10f", __testlib_points)); + std::fprintf(resultFile, "", + outcomes[(int) result].c_str(), stringPoints.c_str()); + } + } + xmlSafeWrite(resultFile, __testlib_toPrintableMessage(message).c_str()); + std::fprintf(resultFile, "\n"); + } else + std::fprintf(resultFile, "%s", __testlib_toPrintableMessage(message).c_str()); + if (NULL == resultFile || fclose(resultFile) != 0) { + resultName = ""; + quit(_fail, "Can not write to the result file"); + } + } + + quitscr(LightGray, __testlib_toPrintableMessage(message).c_str()); + std::fprintf(stderr, "\n"); + + inf.close(); + ouf.close(); + ans.close(); + if (tout.is_open()) + tout.close(); + + textColor(LightGray); + + if (resultName != "") + std::fprintf(stderr, "See file to check exit message\n"); + + halt(resultExitCode(result)); +} + +#ifdef __GNUC__ +__attribute__ ((format (printf, 3, 4))) +#endif +NORETURN void InStream::quitf(TResult result, const char *msg, ...) { + FMT_TO_RESULT(msg, msg, message); + InStream::quit(result, message.c_str()); +} + +#ifdef __GNUC__ +__attribute__ ((format (printf, 4, 5))) +#endif +void InStream::quitif(bool condition, TResult result, const char *msg, ...) { + if (condition) { + FMT_TO_RESULT(msg, msg, message); + InStream::quit(result, message.c_str()); + } +} + +NORETURN void InStream::quits(TResult result, std::string msg) { + InStream::quit(result, msg.c_str()); +} + +void InStream::xmlSafeWrite(std::FILE *file, const char *msg) { + size_t lmsg = strlen(msg); + for (size_t i = 0; i < lmsg; i++) { + if (msg[i] == '&') { + std::fprintf(file, "%s", "&"); + continue; + } + if (msg[i] == '<') { + std::fprintf(file, "%s", "<"); + continue; + } + if (msg[i] == '>') { + std::fprintf(file, "%s", ">"); + continue; + } + if (msg[i] == '"') { + std::fprintf(file, "%s", """); + continue; + } + if (0 <= msg[i] && msg[i] <= 31) { + std::fprintf(file, "%c", '.'); + continue; + } + std::fprintf(file, "%c", msg[i]); + } +} + +void InStream::quitscrS(WORD color, std::string msg) { + quitscr(color, msg.c_str()); +} + +void InStream::quitscr(WORD color, const char *msg) { + if (resultName == "") { + textColor(color); + std::fprintf(stderr, "%s", msg); + textColor(LightGray); + } +} + +void InStream::reset(std::FILE *file) { + if (opened && stdfile) + quit(_fail, "Can't reset standard handle"); + + if (opened) + close(); + + if (!stdfile && NULL == file) + if (NULL == (file = std::fopen(name.c_str(), "rb"))) { + if (mode == _output) + quits(_pe, std::string("Output file not found: \"") + name + "\""); + + if (mode == _answer) + quits(_fail, std::string("Answer file not found: \"") + name + "\""); + } + + if (NULL != file) { + opened = true; + __testlib_set_binary(file); + + if (stdfile) + reader = new FileInputStreamReader(file, name); + else + reader = new BufferedFileInputStreamReader(file, name); + } else { + opened = false; + reader = NULL; + } +} + +void InStream::init(std::string fileName, TMode mode) { + opened = false; + name = fileName; + stdfile = false; + this->mode = mode; + + std::ifstream stream; + stream.open(fileName.c_str(), std::ios::in); + if (stream.is_open()) { + std::streampos start = stream.tellg(); + stream.seekg(0, std::ios::end); + std::streampos end = stream.tellg(); + size_t fileSize = size_t(end - start); + stream.close(); + + // You can change maxFileSize. + // Example: 'inf.maxFileSize = 256 * 1024 * 1024;'. + if (fileSize > maxFileSize) + quitf(_pe, "File size exceeds %d bytes, size is %d", int(maxFileSize), int(fileSize)); + } + + reset(); + skipBom(); +} + +void InStream::init(std::FILE *f, TMode mode) { + opened = false; + name = "untitled"; + this->mode = mode; + + if (f == stdin) + name = "stdin", stdfile = true; + if (f == stdout) + name = "stdout", stdfile = true; + if (f == stderr) + name = "stderr", stdfile = true; + + reset(f); + skipBom(); +} + +void InStream::skipBom() { + const std::string utf8Bom = "\xEF\xBB\xBF"; + size_t index = 0; + while (index < utf8Bom.size() && curChar() == utf8Bom[index]) { + index++; + skipChar(); + } + if (index < utf8Bom.size()) { + while (index != 0) { + unreadChar(utf8Bom[index - 1]); + index--; + } + } +} + +char InStream::curChar() { + return char(reader->curChar()); +} + +char InStream::nextChar() { + return char(reader->nextChar()); +} + +char InStream::readChar() { + return nextChar(); +} + +char InStream::readChar(char c) { + lastLine = reader->getLine(); + char found = readChar(); + if (c != found) { + if (!isEoln(found)) + quit(_pe, ("Unexpected character '" + std::string(1, found) + "', but '" + std::string(1, c) + + "' expected").c_str()); + else + quit(_pe, ("Unexpected character " + ("#" + vtos(int(found))) + ", but '" + std::string(1, c) + + "' expected").c_str()); + } + return found; +} + +char InStream::readSpace() { + return readChar(' '); +} + +void InStream::unreadChar(char c) { + reader->unreadChar(c); +} + +void InStream::skipChar() { + reader->skipChar(); +} + +void InStream::skipBlanks() { + while (isBlanks(reader->curChar())) + reader->skipChar(); +} + +std::string InStream::readWord() { + readWordTo(_tmpReadToken); + return _tmpReadToken; +} + +void InStream::readWordTo(std::string &result) { + if (!strict) + skipBlanks(); + + lastLine = reader->getLine(); + int cur = reader->nextChar(); + + if (cur == EOFC) + quit(_unexpected_eof, "Unexpected end of file - token expected"); + + if (isBlanks(cur)) + quit(_pe, "Unexpected white-space - token expected"); + + result.clear(); + + while (!(isBlanks(cur) || cur == EOFC)) { + result += char(cur); + + // You can change maxTokenLength. + // Example: 'inf.maxTokenLength = 128 * 1024 * 1024;'. + if (result.length() > maxTokenLength) + quitf(_pe, "Length of token exceeds %d, token is '%s...'", int(maxTokenLength), + __testlib_part(result).c_str()); + + cur = reader->nextChar(); + } + + reader->unreadChar(cur); + + if (result.length() == 0) + quit(_unexpected_eof, "Unexpected end of file or white-space - token expected"); +} + +std::string InStream::readToken() { + return readWord(); +} + +void InStream::readTokenTo(std::string &result) { + readWordTo(result); +} + +static std::string __testlib_part(const std::string &s) { + std::string t; + for (size_t i = 0; i < s.length(); i++) + if (s[i] != '\0') + t += s[i]; + else + t += '~'; + if (t.length() <= 64) + return t; + else + return t.substr(0, 30) + "..." + t.substr(s.length() - 31, 31); +} + +#define __testlib_readMany(readMany, readOne, typeName, space) \ + if (size < 0) \ + quit(_fail, #readMany ": size should be non-negative."); \ + if (size > 100000000) \ + quit(_fail, #readMany ": size should be at most 100000000."); \ + \ + std::vector result(size); \ + readManyIteration = indexBase; \ + \ + for (int i = 0; i < size; i++) \ + { \ + result[i] = readOne; \ + readManyIteration++; \ + if (strict && space && i + 1 < size) \ + readSpace(); \ + } \ + \ + readManyIteration = NO_INDEX; \ + return result; \ + + +std::string InStream::readWord(const pattern &p, const std::string &variableName) { + readWordTo(_tmpReadToken); + if (!p.matches(_tmpReadToken)) { + if (readManyIteration == NO_INDEX) { + if (variableName.empty()) + quit(_wa, + ("Token \"" + __testlib_part(_tmpReadToken) + "\" doesn't correspond to pattern \"" + p.src() + + "\"").c_str()); + else + quit(_wa, ("Token parameter [name=" + variableName + "] equals to \"" + __testlib_part(_tmpReadToken) + + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str()); + } else { + if (variableName.empty()) + quit(_wa, ("Token element [index=" + vtos(readManyIteration) + "] equals to \"" + + __testlib_part(_tmpReadToken) + "\" doesn't correspond to pattern \"" + p.src() + + "\"").c_str()); + else + quit(_wa, ("Token element " + variableName + "[" + vtos(readManyIteration) + "] equals to \"" + + __testlib_part(_tmpReadToken) + "\", doesn't correspond to pattern \"" + p.src() + + "\"").c_str()); + } + } + return _tmpReadToken; +} + +std::vector +InStream::readWords(int size, const pattern &p, const std::string &variablesName, int indexBase) { + __testlib_readMany(readWords, readWord(p, variablesName), std::string, true); +} + +std::vector InStream::readWords(int size, int indexBase) { + __testlib_readMany(readWords, readWord(), std::string, true); +} + +std::string InStream::readWord(const std::string &ptrn, const std::string &variableName) { + return readWord(pattern(ptrn), variableName); +} + +std::vector +InStream::readWords(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) { + pattern p(ptrn); + __testlib_readMany(readWords, readWord(p, variablesName), std::string, true); +} + +std::string InStream::readToken(const pattern &p, const std::string &variableName) { + return readWord(p, variableName); +} + +std::vector +InStream::readTokens(int size, const pattern &p, const std::string &variablesName, int indexBase) { + __testlib_readMany(readTokens, readToken(p, variablesName), std::string, true); +} + +std::vector InStream::readTokens(int size, int indexBase) { + __testlib_readMany(readTokens, readToken(), std::string, true); +} + +std::string InStream::readToken(const std::string &ptrn, const std::string &variableName) { + return readWord(ptrn, variableName); +} + +std::vector +InStream::readTokens(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) { + pattern p(ptrn); + __testlib_readMany(readTokens, readWord(p, variablesName), std::string, true); +} + +void InStream::readWordTo(std::string &result, const pattern &p, const std::string &variableName) { + readWordTo(result); + if (!p.matches(result)) { + if (variableName.empty()) + quit(_wa, ("Token \"" + __testlib_part(result) + "\" doesn't correspond to pattern \"" + p.src() + + "\"").c_str()); + else + quit(_wa, ("Token parameter [name=" + variableName + "] equals to \"" + __testlib_part(result) + + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str()); + } +} + +void InStream::readWordTo(std::string &result, const std::string &ptrn, const std::string &variableName) { + return readWordTo(result, pattern(ptrn), variableName); +} + +void InStream::readTokenTo(std::string &result, const pattern &p, const std::string &variableName) { + return readWordTo(result, p, variableName); +} + +void InStream::readTokenTo(std::string &result, const std::string &ptrn, const std::string &variableName) { + return readWordTo(result, ptrn, variableName); +} + +#ifdef __GNUC__ +__attribute__((pure)) +#endif +static inline bool equals(long long integer, const char *s) { + if (integer == LLONG_MIN) + return strcmp(s, "-9223372036854775808") == 0; + + if (integer == 0LL) + return strcmp(s, "0") == 0; + + size_t length = strlen(s); + + if (length == 0) + return false; + + if (integer < 0 && s[0] != '-') + return false; + + if (integer < 0) + s++, length--, integer = -integer; + + if (length == 0) + return false; + + while (integer > 0) { + int digit = int(integer % 10); + + if (s[length - 1] != '0' + digit) + return false; + + length--; + integer /= 10; + } + + return length == 0; +} + +#ifdef __GNUC__ +__attribute__((pure)) +#endif +static inline bool equals(unsigned long long integer, const char *s) { + if (integer == ULLONG_MAX) + return strcmp(s, "18446744073709551615") == 0; + + if (integer == 0ULL) + return strcmp(s, "0") == 0; + + size_t length = strlen(s); + + if (length == 0) + return false; + + while (integer > 0) { + int digit = int(integer % 10); + + if (s[length - 1] != '0' + digit) + return false; + + length--; + integer /= 10; + } + + return length == 0; +} + +static inline double stringToDouble(InStream &in, const char *buffer) { + double retval; + + size_t length = strlen(buffer); + + int minusCount = 0; + int plusCount = 0; + int decimalPointCount = 0; + int digitCount = 0; + int eCount = 0; + + for (size_t i = 0; i < length; i++) { + if (('0' <= buffer[i] && buffer[i] <= '9') || buffer[i] == '.' + || buffer[i] == 'e' || buffer[i] == 'E' + || buffer[i] == '-' || buffer[i] == '+') { + if ('0' <= buffer[i] && buffer[i] <= '9') + digitCount++; + if (buffer[i] == 'e' || buffer[i] == 'E') + eCount++; + if (buffer[i] == '-') + minusCount++; + if (buffer[i] == '+') + plusCount++; + if (buffer[i] == '.') + decimalPointCount++; + } else + in.quit(_pe, ("Expected double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + } + + // If for sure is not a number in standard notation or in e-notation. + if (digitCount == 0 || minusCount > 2 || plusCount > 2 || decimalPointCount > 1 || eCount > 1) + in.quit(_pe, ("Expected double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + char *suffix = new char[length + 1]; + std::memset(suffix, 0, length + 1); + int scanned = std::sscanf(buffer, "%lf%s", &retval, suffix); + bool empty = strlen(suffix) == 0; + delete[] suffix; + + if (scanned == 1 || (scanned == 2 && empty)) { + if (__testlib_isNaN(retval)) + in.quit(_pe, ("Expected double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + return retval; + } else + in.quit(_pe, ("Expected double, but \"" + __testlib_part(buffer) + "\" found").c_str()); +} + +static inline double stringToDouble(InStream &in, const std::string& buffer) { + for (size_t i = 0; i < buffer.length(); i++) + if (buffer[i] == '\0') + in.quit(_pe, ("Expected double, but \"" + __testlib_part(buffer) + "\" found (it contains \\0)").c_str()); + return stringToDouble(in, buffer.c_str()); +} + +static inline double stringToStrictDouble(InStream &in, const char *buffer, + int minAfterPointDigitCount, int maxAfterPointDigitCount) { + if (minAfterPointDigitCount < 0) + in.quit(_fail, "stringToStrictDouble: minAfterPointDigitCount should be non-negative."); + + if (minAfterPointDigitCount > maxAfterPointDigitCount) + in.quit(_fail, + "stringToStrictDouble: minAfterPointDigitCount should be less or equal to maxAfterPointDigitCount."); + + double retval; + + size_t length = strlen(buffer); + + if (length == 0 || length > 1000) + in.quit(_pe, ("Expected strict double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + if (buffer[0] != '-' && (buffer[0] < '0' || buffer[0] > '9')) + in.quit(_pe, ("Expected strict double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + int pointPos = -1; + for (size_t i = 1; i + 1 < length; i++) { + if (buffer[i] == '.') { + if (pointPos > -1) + in.quit(_pe, ("Expected strict double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + pointPos = int(i); + } + if (buffer[i] != '.' && (buffer[i] < '0' || buffer[i] > '9')) + in.quit(_pe, ("Expected strict double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + } + + if (buffer[length - 1] < '0' || buffer[length - 1] > '9') + in.quit(_pe, ("Expected strict double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + int afterDigitsCount = (pointPos == -1 ? 0 : int(length) - pointPos - 1); + if (afterDigitsCount < minAfterPointDigitCount || afterDigitsCount > maxAfterPointDigitCount) + in.quit(_pe, ("Expected strict double with number of digits after point in range [" + + vtos(minAfterPointDigitCount) + + "," + + vtos(maxAfterPointDigitCount) + + "], but \"" + __testlib_part(buffer) + "\" found").c_str() + ); + + int firstDigitPos = -1; + for (size_t i = 0; i < length; i++) + if (buffer[i] >= '0' && buffer[i] <= '9') { + firstDigitPos = int(i); + break; + } + + if (firstDigitPos > 1 || firstDigitPos == -1) + in.quit(_pe, ("Expected strict double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + if (buffer[firstDigitPos] == '0' && firstDigitPos + 1 < int(length) + && buffer[firstDigitPos + 1] >= '0' && buffer[firstDigitPos + 1] <= '9') + in.quit(_pe, ("Expected strict double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + char *suffix = new char[length + 1]; + std::memset(suffix, 0, length + 1); + int scanned = std::sscanf(buffer, "%lf%s", &retval, suffix); + bool empty = strlen(suffix) == 0; + delete[] suffix; + + if (scanned == 1 || (scanned == 2 && empty)) { + if (__testlib_isNaN(retval) || __testlib_isInfinite(retval)) + in.quit(_pe, ("Expected double, but \"" + __testlib_part(buffer) + "\" found").c_str()); + if (buffer[0] == '-' && retval >= 0) + in.quit(_pe, ("Redundant minus in \"" + __testlib_part(buffer) + "\" found").c_str()); + return retval; + } else + in.quit(_pe, ("Expected double, but \"" + __testlib_part(buffer) + "\" found").c_str()); +} + +static inline double stringToStrictDouble(InStream &in, const std::string& buffer, + int minAfterPointDigitCount, int maxAfterPointDigitCount) { + for (size_t i = 0; i < buffer.length(); i++) + if (buffer[i] == '\0') + in.quit(_pe, ("Expected double, but \"" + __testlib_part(buffer) + "\" found (it contains \\0)").c_str()); + return stringToStrictDouble(in, buffer.c_str(), minAfterPointDigitCount, maxAfterPointDigitCount); +} + +static inline long long stringToLongLong(InStream &in, const char *buffer) { + if (strcmp(buffer, "-9223372036854775808") == 0) + return LLONG_MIN; + + bool minus = false; + size_t length = strlen(buffer); + + if (length > 1 && buffer[0] == '-') + minus = true; + + if (length > 20) + in.quit(_pe, ("Expected integer, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + long long retval = 0LL; + + int zeroes = 0; + bool processingZeroes = true; + + for (int i = (minus ? 1 : 0); i < int(length); i++) { + if (buffer[i] == '0' && processingZeroes) + zeroes++; + else + processingZeroes = false; + + if (buffer[i] < '0' || buffer[i] > '9') + in.quit(_pe, ("Expected integer, but \"" + __testlib_part(buffer) + "\" found").c_str()); + retval = retval * 10 + (buffer[i] - '0'); + } + + if (retval < 0) + in.quit(_pe, ("Expected integer, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + if ((zeroes > 0 && (retval != 0 || minus)) || zeroes > 1) + in.quit(_pe, ("Expected integer, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + retval = (minus ? -retval : +retval); + + if (length < 19) + return retval; + + if (equals(retval, buffer)) + return retval; + else + in.quit(_pe, ("Expected int64, but \"" + __testlib_part(buffer) + "\" found").c_str()); +} + +static inline long long stringToLongLong(InStream &in, const std::string& buffer) { + for (size_t i = 0; i < buffer.length(); i++) + if (buffer[i] == '\0') + in.quit(_pe, ("Expected integer, but \"" + __testlib_part(buffer) + "\" found (it contains \\0)").c_str()); + return stringToLongLong(in, buffer.c_str()); +} + +static inline unsigned long long stringToUnsignedLongLong(InStream &in, const char *buffer) { + size_t length = strlen(buffer); + + if (length > 20) + in.quit(_pe, ("Expected unsigned integer, but \"" + __testlib_part(buffer) + "\" found").c_str()); + if (length > 1 && buffer[0] == '0') + in.quit(_pe, ("Expected unsigned integer, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + unsigned long long retval = 0LL; + for (int i = 0; i < int(length); i++) { + if (buffer[i] < '0' || buffer[i] > '9') + in.quit(_pe, ("Expected unsigned integer, but \"" + __testlib_part(buffer) + "\" found").c_str()); + retval = retval * 10 + (buffer[i] - '0'); + } + + if (length < 19) + return retval; + + if (length == 20 && strcmp(buffer, "18446744073709551615") > 0) + in.quit(_pe, ("Expected unsigned int64, but \"" + __testlib_part(buffer) + "\" found").c_str()); + + if (equals(retval, buffer)) + return retval; + else + in.quit(_pe, ("Expected unsigned int64, but \"" + __testlib_part(buffer) + "\" found").c_str()); +} + +static inline long long stringToUnsignedLongLong(InStream &in, const std::string& buffer) { + for (size_t i = 0; i < buffer.length(); i++) + if (buffer[i] == '\0') + in.quit(_pe, ("Expected unsigned integer, but \"" + __testlib_part(buffer) + "\" found (it contains \\0)").c_str()); + return stringToUnsignedLongLong(in, buffer.c_str()); +} + +int InStream::readInteger() { + if (!strict && seekEof()) + quit(_unexpected_eof, "Unexpected end of file - int32 expected"); + + readWordTo(_tmpReadToken); + + long long value = stringToLongLong(*this, _tmpReadToken); + if (value < INT_MIN || value > INT_MAX) + quit(_pe, ("Expected int32, but \"" + __testlib_part(_tmpReadToken) + "\" found").c_str()); + + return int(value); +} + +long long InStream::readLong() { + if (!strict && seekEof()) + quit(_unexpected_eof, "Unexpected end of file - int64 expected"); + + readWordTo(_tmpReadToken); + + return stringToLongLong(*this, _tmpReadToken); +} + +unsigned long long InStream::readUnsignedLong() { + if (!strict && seekEof()) + quit(_unexpected_eof, "Unexpected end of file - int64 expected"); + + readWordTo(_tmpReadToken); + + return stringToUnsignedLongLong(*this, _tmpReadToken); +} + +long long InStream::readLong(long long minv, long long maxv, const std::string &variableName) { + long long result = readLong(); + + if (result < minv || result > maxv) { + if (readManyIteration == NO_INDEX) { + if (variableName.empty()) + quit(_wa, ("Integer " + vtos(result) + " violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + + "]").c_str()); + else + quit(_wa, ("Integer parameter [name=" + std::string(variableName) + "] equals to " + vtos(result) + + ", violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + "]").c_str()); + } else { + if (variableName.empty()) + quit(_wa, ("Integer element [index=" + vtos(readManyIteration) + "] equals to " + vtos(result) + + ", violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + "]").c_str()); + else + quit(_wa, + ("Integer element " + std::string(variableName) + "[" + vtos(readManyIteration) + "] equals to " + + vtos(result) + ", violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + "]").c_str()); + } + } + + if (strict && !variableName.empty()) + validator.addBoundsHit(variableName, ValidatorBoundsHit(minv == result, maxv == result)); + + return result; +} + +std::vector +InStream::readLongs(int size, long long minv, long long maxv, const std::string &variablesName, int indexBase) { + __testlib_readMany(readLongs, readLong(minv, maxv, variablesName), long long, true) +} + +std::vector InStream::readLongs(int size, int indexBase) { + __testlib_readMany(readLongs, readLong(), long long, true) +} + +unsigned long long +InStream::readUnsignedLong(unsigned long long minv, unsigned long long maxv, const std::string &variableName) { + unsigned long long result = readUnsignedLong(); + + if (result < minv || result > maxv) { + if (readManyIteration == NO_INDEX) { + if (variableName.empty()) + quit(_wa, + ("Unsigned integer " + vtos(result) + " violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + + "]").c_str()); + else + quit(_wa, + ("Unsigned integer parameter [name=" + std::string(variableName) + "] equals to " + vtos(result) + + ", violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + "]").c_str()); + } else { + if (variableName.empty()) + quit(_wa, + ("Unsigned integer element [index=" + vtos(readManyIteration) + "] equals to " + vtos(result) + + ", violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + "]").c_str()); + else + quit(_wa, ("Unsigned integer element " + std::string(variableName) + "[" + vtos(readManyIteration) + + "] equals to " + vtos(result) + ", violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + + "]").c_str()); + } + } + + if (strict && !variableName.empty()) + validator.addBoundsHit(variableName, ValidatorBoundsHit(minv == result, maxv == result)); + + return result; +} + +std::vector InStream::readUnsignedLongs(int size, unsigned long long minv, unsigned long long maxv, + const std::string &variablesName, int indexBase) { + __testlib_readMany(readUnsignedLongs, readUnsignedLong(minv, maxv, variablesName), unsigned long long, true) +} + +std::vector InStream::readUnsignedLongs(int size, int indexBase) { + __testlib_readMany(readUnsignedLongs, readUnsignedLong(), unsigned long long, true) +} + +unsigned long long +InStream::readLong(unsigned long long minv, unsigned long long maxv, const std::string &variableName) { + return readUnsignedLong(minv, maxv, variableName); +} + +int InStream::readInt() { + return readInteger(); +} + +int InStream::readInt(int minv, int maxv, const std::string &variableName) { + int result = readInt(); + + if (result < minv || result > maxv) { + if (readManyIteration == NO_INDEX) { + if (variableName.empty()) + quit(_wa, ("Integer " + vtos(result) + " violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + + "]").c_str()); + else + quit(_wa, ("Integer parameter [name=" + std::string(variableName) + "] equals to " + vtos(result) + + ", violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + "]").c_str()); + } else { + if (variableName.empty()) + quit(_wa, ("Integer element [index=" + vtos(readManyIteration) + "] equals to " + vtos(result) + + ", violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + "]").c_str()); + else + quit(_wa, + ("Integer element " + std::string(variableName) + "[" + vtos(readManyIteration) + "] equals to " + + vtos(result) + ", violates the range [" + toHumanReadableString(minv) + ", " + toHumanReadableString(maxv) + "]").c_str()); + } + } + + if (strict && !variableName.empty()) + validator.addBoundsHit(variableName, ValidatorBoundsHit(minv == result, maxv == result)); + + return result; +} + +int InStream::readInteger(int minv, int maxv, const std::string &variableName) { + return readInt(minv, maxv, variableName); +} + +std::vector InStream::readInts(int size, int minv, int maxv, const std::string &variablesName, int indexBase) { + __testlib_readMany(readInts, readInt(minv, maxv, variablesName), int, true) +} + +std::vector InStream::readInts(int size, int indexBase) { + __testlib_readMany(readInts, readInt(), int, true) +} + +std::vector InStream::readIntegers(int size, int minv, int maxv, const std::string &variablesName, int indexBase) { + __testlib_readMany(readIntegers, readInt(minv, maxv, variablesName), int, true) +} + +std::vector InStream::readIntegers(int size, int indexBase) { + __testlib_readMany(readIntegers, readInt(), int, true) +} + +double InStream::readReal() { + if (!strict && seekEof()) + quit(_unexpected_eof, "Unexpected end of file - double expected"); + + return stringToDouble(*this, readWord()); +} + +double InStream::readDouble() { + return readReal(); +} + +double InStream::readReal(double minv, double maxv, const std::string &variableName) { + double result = readReal(); + + if (result < minv || result > maxv) { + if (readManyIteration == NO_INDEX) { + if (variableName.empty()) + quit(_wa, ("Double " + vtos(result) + " violates the range [" + vtos(minv) + ", " + vtos(maxv) + + "]").c_str()); + else + quit(_wa, ("Double parameter [name=" + std::string(variableName) + "] equals to " + vtos(result) + + ", violates the range [" + vtos(minv) + ", " + vtos(maxv) + "]").c_str()); + } else { + if (variableName.empty()) + quit(_wa, ("Double element [index=" + vtos(readManyIteration) + "] equals to " + vtos(result) + + ", violates the range [" + vtos(minv) + ", " + vtos(maxv) + "]").c_str()); + else + quit(_wa, + ("Double element " + std::string(variableName) + "[" + vtos(readManyIteration) + "] equals to " + + vtos(result) + ", violates the range [" + vtos(minv) + ", " + vtos(maxv) + "]").c_str()); + } + } + + if (strict && !variableName.empty()) + validator.addBoundsHit(variableName, ValidatorBoundsHit( + doubleDelta(minv, result) < ValidatorBoundsHit::EPS, + doubleDelta(maxv, result) < ValidatorBoundsHit::EPS + )); + + return result; +} + +std::vector +InStream::readReals(int size, double minv, double maxv, const std::string &variablesName, int indexBase) { + __testlib_readMany(readReals, readReal(minv, maxv, variablesName), double, true) +} + +std::vector InStream::readReals(int size, int indexBase) { + __testlib_readMany(readReals, readReal(), double, true) +} + +double InStream::readDouble(double minv, double maxv, const std::string &variableName) { + return readReal(minv, maxv, variableName); +} + +std::vector +InStream::readDoubles(int size, double minv, double maxv, const std::string &variablesName, int indexBase) { + __testlib_readMany(readDoubles, readDouble(minv, maxv, variablesName), double, true) +} + +std::vector InStream::readDoubles(int size, int indexBase) { + __testlib_readMany(readDoubles, readDouble(), double, true) +} + +double InStream::readStrictReal(double minv, double maxv, + int minAfterPointDigitCount, int maxAfterPointDigitCount, + const std::string &variableName) { + if (!strict && seekEof()) + quit(_unexpected_eof, "Unexpected end of file - strict double expected"); + + double result = stringToStrictDouble(*this, readWord(), minAfterPointDigitCount, maxAfterPointDigitCount); + + if (result < minv || result > maxv) { + if (readManyIteration == NO_INDEX) { + if (variableName.empty()) + quit(_wa, ("Strict double " + vtos(result) + " violates the range [" + vtos(minv) + ", " + vtos(maxv) + + "]").c_str()); + else + quit(_wa, + ("Strict double parameter [name=" + std::string(variableName) + "] equals to " + vtos(result) + + ", violates the range [" + vtos(minv) + ", " + vtos(maxv) + "]").c_str()); + } else { + if (variableName.empty()) + quit(_wa, ("Strict double element [index=" + vtos(readManyIteration) + "] equals to " + vtos(result) + + ", violates the range [" + vtos(minv) + ", " + vtos(maxv) + "]").c_str()); + else + quit(_wa, ("Strict double element " + std::string(variableName) + "[" + vtos(readManyIteration) + + "] equals to " + vtos(result) + ", violates the range [" + vtos(minv) + ", " + vtos(maxv) + + "]").c_str()); + } + } + + if (strict && !variableName.empty()) + validator.addBoundsHit(variableName, ValidatorBoundsHit( + doubleDelta(minv, result) < ValidatorBoundsHit::EPS, + doubleDelta(maxv, result) < ValidatorBoundsHit::EPS + )); + + return result; +} + +std::vector InStream::readStrictReals(int size, double minv, double maxv, + int minAfterPointDigitCount, int maxAfterPointDigitCount, + const std::string &variablesName, int indexBase) { + __testlib_readMany(readStrictReals, + readStrictReal(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName), + double, true) +} + +double InStream::readStrictDouble(double minv, double maxv, + int minAfterPointDigitCount, int maxAfterPointDigitCount, + const std::string &variableName) { + return readStrictReal(minv, maxv, + minAfterPointDigitCount, maxAfterPointDigitCount, + variableName); +} + +std::vector InStream::readStrictDoubles(int size, double minv, double maxv, + int minAfterPointDigitCount, int maxAfterPointDigitCount, + const std::string &variablesName, int indexBase) { + __testlib_readMany(readStrictDoubles, + readStrictDouble(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName), + double, true) +} + +bool InStream::eof() { + if (!strict && NULL == reader) + return true; + + return reader->eof(); +} + +bool InStream::seekEof() { + if (!strict && NULL == reader) + return true; + skipBlanks(); + return eof(); +} + +bool InStream::eoln() { + if (!strict && NULL == reader) + return true; + + int c = reader->nextChar(); + + if (!strict) { + if (c == EOFC) + return true; + + if (c == CR) { + c = reader->nextChar(); + + if (c != LF) { + reader->unreadChar(c); + reader->unreadChar(CR); + return false; + } else + return true; + } + + if (c == LF) + return true; + + reader->unreadChar(c); + return false; + } else { + bool returnCr = false; + +#if (defined(ON_WINDOWS) && !defined(FOR_LINUX)) || defined(FOR_WINDOWS) + if (c != CR) { + reader->unreadChar(c); + return false; + } else { + if (!returnCr) + returnCr = true; + c = reader->nextChar(); + } +#endif + if (c != LF) { + reader->unreadChar(c); + if (returnCr) + reader->unreadChar(CR); + return false; + } + + return true; + } +} + +void InStream::readEoln() { + lastLine = reader->getLine(); + if (!eoln()) + quit(_pe, "Expected EOLN"); +} + +void InStream::readEof() { + lastLine = reader->getLine(); + if (!eof()) + quit(_pe, "Expected EOF"); + + if (TestlibFinalizeGuard::alive && this == &inf) + testlibFinalizeGuard.readEofCount++; +} + +bool InStream::seekEoln() { + if (!strict && NULL == reader) + return true; + + int cur; + do { + cur = reader->nextChar(); + } while (cur == SPACE || cur == TAB); + + reader->unreadChar(cur); + return eoln(); +} + +void InStream::nextLine() { + readLine(); +} + +void InStream::readStringTo(std::string &result) { + if (NULL == reader) + quit(_pe, "Expected line"); + + result.clear(); + + for (;;) { + int cur = reader->curChar(); + + if (cur == LF || cur == EOFC) + break; + + if (cur == CR) { + cur = reader->nextChar(); + if (reader->curChar() == LF) { + reader->unreadChar(cur); + break; + } + } + + lastLine = reader->getLine(); + result += char(reader->nextChar()); + } + + if (strict) + readEoln(); + else + eoln(); +} + +std::string InStream::readString() { + readStringTo(_tmpReadToken); + return _tmpReadToken; +} + +std::vector InStream::readStrings(int size, int indexBase) { + __testlib_readMany(readStrings, readString(), std::string, false) +} + +void InStream::readStringTo(std::string &result, const pattern &p, const std::string &variableName) { + readStringTo(result); + if (!p.matches(result)) { + if (readManyIteration == NO_INDEX) { + if (variableName.empty()) + quit(_wa, ("Line \"" + __testlib_part(result) + "\" doesn't correspond to pattern \"" + p.src() + + "\"").c_str()); + else + quit(_wa, ("Line [name=" + variableName + "] equals to \"" + __testlib_part(result) + + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str()); + } else { + if (variableName.empty()) + quit(_wa, + ("Line element [index=" + vtos(readManyIteration) + "] equals to \"" + __testlib_part(result) + + "\" doesn't correspond to pattern \"" + p.src() + "\"").c_str()); + else + quit(_wa, + ("Line element " + std::string(variableName) + "[" + vtos(readManyIteration) + "] equals to \"" + + __testlib_part(result) + "\", doesn't correspond to pattern \"" + p.src() + "\"").c_str()); + } + } +} + +void InStream::readStringTo(std::string &result, const std::string &ptrn, const std::string &variableName) { + readStringTo(result, pattern(ptrn), variableName); +} + +std::string InStream::readString(const pattern &p, const std::string &variableName) { + readStringTo(_tmpReadToken, p, variableName); + return _tmpReadToken; +} + +std::vector +InStream::readStrings(int size, const pattern &p, const std::string &variablesName, int indexBase) { + __testlib_readMany(readStrings, readString(p, variablesName), std::string, false) +} + +std::string InStream::readString(const std::string &ptrn, const std::string &variableName) { + readStringTo(_tmpReadToken, ptrn, variableName); + return _tmpReadToken; +} + +std::vector +InStream::readStrings(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) { + pattern p(ptrn); + __testlib_readMany(readStrings, readString(p, variablesName), std::string, false) +} + +void InStream::readLineTo(std::string &result) { + readStringTo(result); +} + +std::string InStream::readLine() { + return readString(); +} + +std::vector InStream::readLines(int size, int indexBase) { + __testlib_readMany(readLines, readString(), std::string, false) +} + +void InStream::readLineTo(std::string &result, const pattern &p, const std::string &variableName) { + readStringTo(result, p, variableName); +} + +void InStream::readLineTo(std::string &result, const std::string &ptrn, const std::string &variableName) { + readStringTo(result, ptrn, variableName); +} + +std::string InStream::readLine(const pattern &p, const std::string &variableName) { + return readString(p, variableName); +} + +std::vector +InStream::readLines(int size, const pattern &p, const std::string &variablesName, int indexBase) { + __testlib_readMany(readLines, readString(p, variablesName), std::string, false) +} + +std::string InStream::readLine(const std::string &ptrn, const std::string &variableName) { + return readString(ptrn, variableName); +} + +std::vector +InStream::readLines(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) { + pattern p(ptrn); + __testlib_readMany(readLines, readString(p, variablesName), std::string, false) +} + +#ifdef __GNUC__ +__attribute__ ((format (printf, 3, 4))) +#endif +void InStream::ensuref(bool cond, const char *format, ...) { + if (!cond) { + FMT_TO_RESULT(format, format, message); + this->__testlib_ensure(cond, message); + } +} + +void InStream::__testlib_ensure(bool cond, std::string message) { + if (!cond) + this->quit(_wa, message.c_str()); +} + +void InStream::close() { + if (NULL != reader) { + reader->close(); + delete reader; + reader = NULL; + } + + opened = false; +} + +NORETURN void quit(TResult result, const std::string &msg) { + ouf.quit(result, msg.c_str()); +} + +NORETURN void quit(TResult result, const char *msg) { + ouf.quit(result, msg); +} + +NORETURN void __testlib_quitp(double points, const char *message) { + __testlib_points = points; + std::string stringPoints = removeDoubleTrailingZeroes(format("%.10f", points)); + + std::string quitMessage; + if (NULL == message || 0 == strlen(message)) + quitMessage = stringPoints; + else + quitMessage = stringPoints + " " + message; + + quit(_points, quitMessage.c_str()); +} + +NORETURN void __testlib_quitp(int points, const char *message) { + __testlib_points = points; + std::string stringPoints = format("%d", points); + + std::string quitMessage; + if (NULL == message || 0 == strlen(message)) + quitMessage = stringPoints; + else + quitMessage = stringPoints + " " + message; + + quit(_points, quitMessage.c_str()); +} + +NORETURN void quitp(float points, const std::string &message = "") { + __testlib_quitp(double(points), message.c_str()); +} + +NORETURN void quitp(double points, const std::string &message = "") { + __testlib_quitp(points, message.c_str()); +} + +NORETURN void quitp(long double points, const std::string &message = "") { + __testlib_quitp(double(points), message.c_str()); +} + +NORETURN void quitp(int points, const std::string &message = "") { + __testlib_quitp(points, message.c_str()); +} + +NORETURN void quitpi(const std::string &points_info, const std::string &message = "") { + if (points_info.find(' ') != std::string::npos) + quit(_fail, "Parameter 'points_info' can't contain spaces"); + if (message.empty()) + quit(_points, ("points_info=" + points_info).c_str()); + else + quit(_points, ("points_info=" + points_info + " " + message).c_str()); +} + +template +#ifdef __GNUC__ +__attribute__ ((format (printf, 2, 3))) +#endif +NORETURN void quitp(F points, const char *format, ...) { + FMT_TO_RESULT(format, format, message); + quitp(points, message); +} + +#ifdef __GNUC__ +__attribute__ ((format (printf, 2, 3))) +#endif +NORETURN void quitf(TResult result, const char *format, ...) { + FMT_TO_RESULT(format, format, message); + quit(result, message); +} + +#ifdef __GNUC__ +__attribute__ ((format (printf, 3, 4))) +#endif +void quitif(bool condition, TResult result, const char *format, ...) { + if (condition) { + FMT_TO_RESULT(format, format, message); + quit(result, message); + } +} + +NORETURN void __testlib_help() { + InStream::textColor(InStream::LightCyan); + std::fprintf(stderr, "TESTLIB %s, https://github.com/MikeMirzayanov/testlib/ ", VERSION); + std::fprintf(stderr, "by Mike Mirzayanov, copyright(c) 2005-2020\n"); + std::fprintf(stderr, "Checker name: \"%s\"\n", checkerName.c_str()); + InStream::textColor(InStream::LightGray); + + std::fprintf(stderr, "\n"); + std::fprintf(stderr, "Latest features: \n"); + for (size_t i = 0; i < sizeof(latestFeatures) / sizeof(char *); i++) { + std::fprintf(stderr, "*) %s\n", latestFeatures[i]); + } + std::fprintf(stderr, "\n"); + + std::fprintf(stderr, "Program must be run with the following arguments: \n"); + std::fprintf(stderr, " [--testset testset] [--group group] [ [<-appes>]]\n\n"); + + __testlib_exitCode = FAIL_EXIT_CODE; + std::exit(FAIL_EXIT_CODE); +} + +static void __testlib_ensuresPreconditions() { + // testlib assumes: sizeof(int) = 4. + __TESTLIB_STATIC_ASSERT(sizeof(int) == 4); + + // testlib assumes: INT_MAX == 2147483647. + __TESTLIB_STATIC_ASSERT(INT_MAX == 2147483647); + + // testlib assumes: sizeof(long long) = 8. + __TESTLIB_STATIC_ASSERT(sizeof(long long) == 8); + + // testlib assumes: sizeof(double) = 8. + __TESTLIB_STATIC_ASSERT(sizeof(double) == 8); + + // testlib assumes: no -ffast-math. + if (!__testlib_isNaN(+__testlib_nan())) + quit(_fail, "Function __testlib_isNaN is not working correctly: possible reason is '-ffast-math'"); + if (!__testlib_isNaN(-__testlib_nan())) + quit(_fail, "Function __testlib_isNaN is not working correctly: possible reason is '-ffast-math'"); +} + +std::string __testlib_testset; + +std::string getTestset() { + return __testlib_testset; +} + +std::string __testlib_group; + +std::string getGroup() { + return __testlib_group; +} + +static void __testlib_set_testset_and_group(int argc, char* argv[]) { + for (int i = 1; i < argc; i++) { + if (!strcmp("--testset", argv[i])) { + if (i + 1 < argc && strlen(argv[i + 1]) > 0) + __testlib_testset = argv[++i]; + else + quit(_fail, std::string("Expected non-empty testset after --testset command line parameter")); + } else if (!strcmp("--group", argv[i])) { + if (i + 1 < argc) + __testlib_group = argv[++i]; + else + quit(_fail, std::string("Expected group after --group command line parameter")); + } + } +} + +void registerGen(int argc, char *argv[], int randomGeneratorVersion) { + if (randomGeneratorVersion < 0 || randomGeneratorVersion > 1) + quitf(_fail, "Random generator version is expected to be 0 or 1."); + random_t::version = randomGeneratorVersion; + + __testlib_ensuresPreconditions(); + TestlibFinalizeGuard::registered = true; + + testlibMode = _generator; + __testlib_set_binary(stdin); + rnd.setSeed(argc, argv); + +#if __cplusplus > 199711L || defined(_MSC_VER) + prepareOpts(argc, argv); +#endif +} + +#ifdef USE_RND_AS_BEFORE_087 +void registerGen(int argc, char* argv[]) +{ + registerGen(argc, argv, 0); +} +#else +#ifdef __GNUC__ +#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 4)) +__attribute__ ((deprecated("Use registerGen(argc, argv, 0) or registerGen(argc, argv, 1)." +" The third parameter stands for the random generator version." +" If you are trying to compile old generator use macro -DUSE_RND_AS_BEFORE_087 or registerGen(argc, argv, 0)." +" Version 1 has been released on Spring, 2013. Use it to write new generators."))) +#else +__attribute__ ((deprecated)) +#endif +#endif +#ifdef _MSC_VER +__declspec(deprecated("Use registerGen(argc, argv, 0) or registerGen(argc, argv, 1)." + " The third parameter stands for the random generator version." + " If you are trying to compile old generator use macro -DUSE_RND_AS_BEFORE_087 or registerGen(argc, argv, 0)." + " Version 1 has been released on Spring, 2013. Use it to write new generators.")) +#endif +void registerGen(int argc, char *argv[]) { + std::fprintf(stderr, "Use registerGen(argc, argv, 0) or registerGen(argc, argv, 1)." + " The third parameter stands for the random generator version." + " If you are trying to compile old generator use macro -DUSE_RND_AS_BEFORE_087 or registerGen(argc, argv, 0)." + " Version 1 has been released on Spring, 2013. Use it to write new generators.\n\n"); + registerGen(argc, argv, 0); +} +#endif + +void registerInteraction(int argc, char *argv[]) { + __testlib_ensuresPreconditions(); + __testlib_set_testset_and_group(argc, argv); + TestlibFinalizeGuard::registered = true; + + testlibMode = _interactor; + __testlib_set_binary(stdin); + + if (argc > 1 && !strcmp("--help", argv[1])) + __testlib_help(); + + if (argc < 3 || argc > 6) { + quit(_fail, std::string("Program must be run with the following arguments: ") + + std::string(" [ [ [<-appes>]]]") + + "\nUse \"--help\" to get help information"); + } + + if (argc <= 4) { + resultName = ""; + appesMode = false; + } + +#ifndef EJUDGE + if (argc == 5) { + resultName = argv[4]; + appesMode = false; + } + + if (argc == 6) { + if (strcmp("-APPES", argv[5]) && strcmp("-appes", argv[5])) { + quit(_fail, std::string("Program must be run with the following arguments: ") + + " [ [<-appes>]]"); + } else { + resultName = argv[4]; + appesMode = true; + } + } +#endif + + inf.init(argv[1], _input); + + tout.open(argv[2], std::ios_base::out); + if (tout.fail() || !tout.is_open()) + quit(_fail, std::string("Can not write to the test-output-file '") + argv[2] + std::string("'")); + + ouf.init(stdin, _output); + + if (argc >= 4) + ans.init(argv[3], _answer); + else + ans.name = "unopened answer stream"; +} + +void registerValidation() { + __testlib_ensuresPreconditions(); + TestlibFinalizeGuard::registered = true; + + testlibMode = _validator; + + __testlib_set_binary(stdin); + __testlib_set_binary(stdout); + __testlib_set_binary(stderr); + + inf.init(stdin, _input); + inf.strict = true; +} + +void registerValidation(int argc, char *argv[]) { + registerValidation(); + __testlib_set_testset_and_group(argc, argv); + + validator.initialize(); + TestlibFinalizeGuard::registered = true; + + std::string comment = "Validator must be run with the following arguments:" + " [--testset testset]" + " [--group group]" + " [--testOverviewLogFileName fileName]" + " [--testMarkupFileName fileName]" + " [--testCase testCase]" + " [--testCaseFileName fileName]" + ; + + for (int i = 1; i < argc; i++) { + if (!strcmp("--testset", argv[i])) { + if (i + 1 < argc && strlen(argv[i + 1]) > 0) + validator.setTestset(argv[++i]); + else + quit(_fail, comment); + } + if (!strcmp("--group", argv[i])) { + if (i + 1 < argc) + validator.setGroup(argv[++i]); + else + quit(_fail, comment); + } + if (!strcmp("--testOverviewLogFileName", argv[i])) { + if (i + 1 < argc) + validator.setTestOverviewLogFileName(argv[++i]); + else + quit(_fail, comment); + } + if (!strcmp("--testMarkupFileName", argv[i])) { + if (i + 1 < argc) + validator.setTestMarkupFileName(argv[++i]); + else + quit(_fail, comment); + } + if (!strcmp("--testCase", argv[i])) { + if (i + 1 < argc) { + long long testCase = stringToLongLong(inf, argv[++i]); + if (testCase < 1 || testCase >= __TESTLIB_MAX_TEST_CASE) + quit(_fail, format("Argument testCase should be between 1 and %d, but ", __TESTLIB_MAX_TEST_CASE) + + toString(testCase) + " found"); + validator.setTestCase(int(testCase)); + } else + quit(_fail, comment); + } + if (!strcmp("--testCaseFileName", argv[i])) { + if (i + 1 < argc) { + validator.setTestCaseFileName(argv[++i]); + } else + quit(_fail, comment); + } + } +} + +void addFeature(const std::string &feature) { + if (testlibMode != _validator) + quit(_fail, "Features are supported in validators only."); + validator.addFeature(feature); +} + +void feature(const std::string &feature) { + if (testlibMode != _validator) + quit(_fail, "Features are supported in validators only."); + validator.feature(feature); +} + +class Checker { +private: + bool _initialized; + std::string _testset; + std::string _group; + +public: + Checker() : _initialized(false), _testset("tests"), _group() { + } + + void initialize() { + _initialized = true; + } + + std::string testset() const { + if (!_initialized) + __testlib_fail("Checker should be initialized with registerTestlibCmd(argc, argv) instead of registerTestlibCmd() to support checker.testset()"); + return _testset; + } + + std::string group() const { + if (!_initialized) + __testlib_fail("Checker should be initialized with registerTestlibCmd(argc, argv) instead of registerTestlibCmd() to support checker.group()"); + return _group; + } + + void setTestset(const char *const testset) { + _testset = testset; + } + + void setGroup(const char *const group) { + _group = group; + } +} checker; + +void registerTestlibCmd(int argc, char *argv[]) { + __testlib_ensuresPreconditions(); + __testlib_set_testset_and_group(argc, argv); + TestlibFinalizeGuard::registered = true; + + testlibMode = _checker; + __testlib_set_binary(stdin); + + std::vector args(1, argv[0]); + checker.initialize(); + + for (int i = 1; i < argc; i++) { + if (!strcmp("--testset", argv[i])) { + if (i + 1 < argc && strlen(argv[i + 1]) > 0) + checker.setTestset(argv[++i]); + else + quit(_fail, std::string("Expected testset after --testset command line parameter")); + } else if (!strcmp("--group", argv[i])) { + if (i + 1 < argc) + checker.setGroup(argv[++i]); + else + quit(_fail, std::string("Expected group after --group command line parameter")); + } else + args.push_back(argv[i]); + } + + argc = int(args.size()); + if (argc > 1 && "--help" == args[1]) + __testlib_help(); + + if (argc < 4 || argc > 6) { + quit(_fail, std::string("Program must be run with the following arguments: ") + + std::string("[--testset testset] [--group group] [ [<-appes>]]") + + "\nUse \"--help\" to get help information"); + } + + if (argc == 4) { + resultName = ""; + appesMode = false; + } + + if (argc == 5) { + resultName = args[4]; + appesMode = false; + } + + if (argc == 6) { + if ("-APPES" != args[5] && "-appes" != args[5]) { + quit(_fail, std::string("Program must be run with the following arguments: ") + + " [ [<-appes>]]"); + } else { + resultName = args[4]; + appesMode = true; + } + } + + #ifdef BOCA_SUPPORT + inf.init(argv[3], _input); + ouf.init(argv[1], _output); + ans.init(argv[2], _answer); + #else + inf.init(argv[1], _input); + ouf.init(argv[2], _output); + ans.init(argv[3], _answer); + #endif +} + +void registerTestlib(int argc, ...) { + if (argc < 3 || argc > 5) + quit(_fail, std::string("Program must be run with the following arguments: ") + + " [ [<-appes>]]"); + + char **argv = new char *[argc + 1]; + + va_list ap; + va_start(ap, argc); + argv[0] = NULL; + for (int i = 0; i < argc; i++) { + argv[i + 1] = va_arg(ap, char*); + } + va_end(ap); + + registerTestlibCmd(argc + 1, argv); + delete[] argv; +} + +static inline void __testlib_ensure(bool cond, const std::string &msg) { + if (!cond) + quit(_fail, msg.c_str()); +} + +#ifdef __GNUC__ +__attribute__((unused)) +#endif +static inline void __testlib_ensure(bool cond, const char *msg) { + if (!cond) + quit(_fail, msg); +} + +#define ensure(cond) __testlib_ensure(cond, "Condition failed: \"" #cond "\"") +#define STRINGIZE_DETAIL(x) #x +#define STRINGIZE(x) STRINGIZE_DETAIL(x) +#define ensure_ext(cond) __testlib_ensure(cond, "Line " STRINGIZE(__LINE__) ": Condition failed: \"" #cond "\"") + +#ifdef __GNUC__ +__attribute__ ((format (printf, 2, 3))) +#endif +inline void ensuref(bool cond, const char *format, ...) { + if (!cond) { + FMT_TO_RESULT(format, format, message); + __testlib_ensure(cond, message); + } +} + +NORETURN static void __testlib_fail(const std::string &message) { + quitf(_fail, "%s", message.c_str()); +} + +#ifdef __GNUC__ +__attribute__ ((format (printf, 1, 2))) +#endif +void setName(const char *format, ...) { + FMT_TO_RESULT(format, format, name); + checkerName = name; +} + +/* + * Do not use random_shuffle, because it will produce different result + * for different C++ compilers. + * + * This implementation uses testlib random_t to produce random numbers, so + * it is stable. + */ +template +void shuffle(_RandomAccessIter __first, _RandomAccessIter __last) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + std::iter_swap(__i, __first + rnd.next(int(__i - __first) + 1)); +} + + +template +#if defined(__GNUC__) && !defined(__clang__) +__attribute__ ((error("Don't use random_shuffle(), use shuffle() instead"))) +#endif +void random_shuffle(_RandomAccessIter, _RandomAccessIter) { + quitf(_fail, "Don't use random_shuffle(), use shuffle() instead"); +} + +#ifdef __GLIBC__ +# define RAND_THROW_STATEMENT throw() +#else +# define RAND_THROW_STATEMENT +#endif + +#if defined(__GNUC__) && !defined(__clang__) + +__attribute__ ((error("Don't use rand(), use rnd.next() instead"))) +#endif +#ifdef _MSC_VER +# pragma warning( disable : 4273 ) +#endif +int rand() RAND_THROW_STATEMENT +{ + quitf(_fail, "Don't use rand(), use rnd.next() instead"); + + /* This line never runs. */ + //throw "Don't use rand(), use rnd.next() instead"; +} + +#if defined(__GNUC__) && !defined(__clang__) + +__attribute__ ((error("Don't use srand(), you should use " +"'registerGen(argc, argv, 1);' to initialize generator seed " +"by hash code of the command line params. The third parameter " +"is randomGeneratorVersion (currently the latest is 1)."))) +#endif +#ifdef _MSC_VER +# pragma warning( disable : 4273 ) +#endif +void srand(unsigned int seed) RAND_THROW_STATEMENT +{ + quitf(_fail, "Don't use srand(), you should use " + "'registerGen(argc, argv, 1);' to initialize generator seed " + "by hash code of the command line params. The third parameter " + "is randomGeneratorVersion (currently the latest is 1) [ignored seed=%u].", seed); +} + +void startTest(int test) { + const std::string testFileName = vtos(test); + if (NULL == freopen(testFileName.c_str(), "wt", stdout)) + __testlib_fail("Unable to write file '" + testFileName + "'"); +} + +inline std::string upperCase(std::string s) { + for (size_t i = 0; i < s.length(); i++) + if ('a' <= s[i] && s[i] <= 'z') + s[i] = char(s[i] - 'a' + 'A'); + return s; +} + +inline std::string lowerCase(std::string s) { + for (size_t i = 0; i < s.length(); i++) + if ('A' <= s[i] && s[i] <= 'Z') + s[i] = char(s[i] - 'A' + 'a'); + return s; +} + +inline std::string compress(const std::string &s) { + return __testlib_part(s); +} + +inline std::string englishEnding(int x) { + x %= 100; + if (x / 10 == 1) + return "th"; + if (x % 10 == 1) + return "st"; + if (x % 10 == 2) + return "nd"; + if (x % 10 == 3) + return "rd"; + return "th"; +} + +template +std::string join(_ForwardIterator first, _ForwardIterator last, _Separator separator) { + std::stringstream ss; + bool repeated = false; + for (_ForwardIterator i = first; i != last; i++) { + if (repeated) + ss << separator; + else + repeated = true; + ss << *i; + } + return ss.str(); +} + +template +std::string join(_ForwardIterator first, _ForwardIterator last) { + return join(first, last, ' '); +} + +template +std::string join(const _Collection &collection, _Separator separator) { + return join(collection.begin(), collection.end(), separator); +} + +template +std::string join(const _Collection &collection) { + return join(collection, ' '); +} + +/** + * Splits string s by character separator returning exactly k+1 items, + * where k is the number of separator occurences. + */ +std::vector split(const std::string &s, char separator) { + std::vector result; + std::string item; + for (size_t i = 0; i < s.length(); i++) + if (s[i] == separator) { + result.push_back(item); + item = ""; + } else + item += s[i]; + result.push_back(item); + return result; +} + +/** + * Splits string s by character separators returning exactly k+1 items, + * where k is the number of separator occurences. + */ +std::vector split(const std::string &s, const std::string &separators) { + if (separators.empty()) + return std::vector(1, s); + + std::vector isSeparator(256); + for (size_t i = 0; i < separators.size(); i++) + isSeparator[(unsigned char) (separators[i])] = true; + + std::vector result; + std::string item; + for (size_t i = 0; i < s.length(); i++) + if (isSeparator[(unsigned char) (s[i])]) { + result.push_back(item); + item = ""; + } else + item += s[i]; + result.push_back(item); + return result; +} + +/** + * Splits string s by character separator returning non-empty items. + */ +std::vector tokenize(const std::string &s, char separator) { + std::vector result; + std::string item; + for (size_t i = 0; i < s.length(); i++) + if (s[i] == separator) { + if (!item.empty()) + result.push_back(item); + item = ""; + } else + item += s[i]; + if (!item.empty()) + result.push_back(item); + return result; +} + +/** + * Splits string s by character separators returning non-empty items. + */ +std::vector tokenize(const std::string &s, const std::string &separators) { + if (separators.empty()) + return std::vector(1, s); + + std::vector isSeparator(256); + for (size_t i = 0; i < separators.size(); i++) + isSeparator[(unsigned char) (separators[i])] = true; + + std::vector result; + std::string item; + for (size_t i = 0; i < s.length(); i++) + if (isSeparator[(unsigned char) (s[i])]) { + if (!item.empty()) + result.push_back(item); + item = ""; + } else + item += s[i]; + + if (!item.empty()) + result.push_back(item); + + return result; +} + +NORETURN void __testlib_expectedButFound(TResult result, std::string expected, std::string found, const char *prepend) { + std::string message; + if (strlen(prepend) != 0) + message = format("%s: expected '%s', but found '%s'", + compress(prepend).c_str(), compress(expected).c_str(), compress(found).c_str()); + else + message = format("expected '%s', but found '%s'", + compress(expected).c_str(), compress(found).c_str()); + quit(result, message); +} + +NORETURN void __testlib_expectedButFound(TResult result, double expected, double found, const char *prepend) { + std::string expectedString = removeDoubleTrailingZeroes(format("%.12f", expected)); + std::string foundString = removeDoubleTrailingZeroes(format("%.12f", found)); + __testlib_expectedButFound(result, expectedString, foundString, prepend); +} + +template +#ifdef __GNUC__ +__attribute__ ((format (printf, 4, 5))) +#endif +NORETURN void expectedButFound(TResult result, T expected, T found, const char *prependFormat = "", ...) { + FMT_TO_RESULT(prependFormat, prependFormat, prepend); + std::string expectedString = vtos(expected); + std::string foundString = vtos(found); + __testlib_expectedButFound(result, expectedString, foundString, prepend.c_str()); +} + +template<> +#ifdef __GNUC__ +__attribute__ ((format (printf, 4, 5))) +#endif +NORETURN void +expectedButFound(TResult result, std::string expected, std::string found, const char *prependFormat, ...) { + FMT_TO_RESULT(prependFormat, prependFormat, prepend); + __testlib_expectedButFound(result, expected, found, prepend.c_str()); +} + +template<> +#ifdef __GNUC__ +__attribute__ ((format (printf, 4, 5))) +#endif +NORETURN void expectedButFound(TResult result, double expected, double found, const char *prependFormat, ...) { + FMT_TO_RESULT(prependFormat, prependFormat, prepend); + std::string expectedString = removeDoubleTrailingZeroes(format("%.12f", expected)); + std::string foundString = removeDoubleTrailingZeroes(format("%.12f", found)); + __testlib_expectedButFound(result, expectedString, foundString, prepend.c_str()); +} + +template<> +#ifdef __GNUC__ +__attribute__ ((format (printf, 4, 5))) +#endif +NORETURN void +expectedButFound(TResult result, const char *expected, const char *found, const char *prependFormat, + ...) { + FMT_TO_RESULT(prependFormat, prependFormat, prepend); + __testlib_expectedButFound(result, std::string(expected), std::string(found), prepend.c_str()); +} + +template<> +#ifdef __GNUC__ +__attribute__ ((format (printf, 4, 5))) +#endif +NORETURN void expectedButFound(TResult result, float expected, float found, const char *prependFormat, ...) { + FMT_TO_RESULT(prependFormat, prependFormat, prepend); + __testlib_expectedButFound(result, double(expected), double(found), prepend.c_str()); +} + +template<> +#ifdef __GNUC__ +__attribute__ ((format (printf, 4, 5))) +#endif +NORETURN void +expectedButFound(TResult result, long double expected, long double found, const char *prependFormat, ...) { + FMT_TO_RESULT(prependFormat, prependFormat, prepend); + __testlib_expectedButFound(result, double(expected), double(found), prepend.c_str()); +} + +#if __cplusplus > 199711L || defined(_MSC_VER) +template +struct is_iterable { + template + static char test(typename U::iterator *x); + + template + static long test(U *x); + + static const bool value = sizeof(test(0)) == 1; +}; + +template +struct __testlib_enable_if { +}; + +template +struct __testlib_enable_if { + typedef T type; +}; + +template +typename __testlib_enable_if::value, void>::type __testlib_print_one(const T &t) { + std::cout << t; +} + +template +typename __testlib_enable_if::value, void>::type __testlib_print_one(const T &t) { + bool first = true; + for (typename T::const_iterator i = t.begin(); i != t.end(); i++) { + if (first) + first = false; + else + std::cout << " "; + std::cout << *i; + } +} + +template<> +typename __testlib_enable_if::value, void>::type +__testlib_print_one(const std::string &t) { + std::cout << t; +} + +template +void __println_range(A begin, B end) { + bool first = true; + for (B i = B(begin); i != end; i++) { + if (first) + first = false; + else + std::cout << " "; + __testlib_print_one(*i); + } + std::cout << std::endl; +} + +template +struct is_iterator { + static T makeT(); + + typedef void *twoptrs[2]; + + static twoptrs &test(...); + + template + static typename R::iterator_category *test(R); + + template + static void *test(R *); + + static const bool value = sizeof(test(makeT())) == sizeof(void *); +}; + +template +struct is_iterator::value>::type> { + static const bool value = false; +}; + +template +typename __testlib_enable_if::value, void>::type println(const A &a, const B &b) { + __testlib_print_one(a); + std::cout << " "; + __testlib_print_one(b); + std::cout << std::endl; +} + +template +typename __testlib_enable_if::value, void>::type println(const A &a, const B &b) { + __println_range(a, b); +} + +template +void println(const A *a, const A *b) { + __println_range(a, b); +} + +template<> +void println(const char *a, const char *b) { + __testlib_print_one(a); + std::cout << " "; + __testlib_print_one(b); + std::cout << std::endl; +} + +template +void println(const T &x) { + __testlib_print_one(x); + std::cout << std::endl; +} + +template +void println(const A &a, const B &b, const C &c) { + __testlib_print_one(a); + std::cout << " "; + __testlib_print_one(b); + std::cout << " "; + __testlib_print_one(c); + std::cout << std::endl; +} + +template +void println(const A &a, const B &b, const C &c, const D &d) { + __testlib_print_one(a); + std::cout << " "; + __testlib_print_one(b); + std::cout << " "; + __testlib_print_one(c); + std::cout << " "; + __testlib_print_one(d); + std::cout << std::endl; +} + +template +void println(const A &a, const B &b, const C &c, const D &d, const E &e) { + __testlib_print_one(a); + std::cout << " "; + __testlib_print_one(b); + std::cout << " "; + __testlib_print_one(c); + std::cout << " "; + __testlib_print_one(d); + std::cout << " "; + __testlib_print_one(e); + std::cout << std::endl; +} + +template +void println(const A &a, const B &b, const C &c, const D &d, const E &e, const F &f) { + __testlib_print_one(a); + std::cout << " "; + __testlib_print_one(b); + std::cout << " "; + __testlib_print_one(c); + std::cout << " "; + __testlib_print_one(d); + std::cout << " "; + __testlib_print_one(e); + std::cout << " "; + __testlib_print_one(f); + std::cout << std::endl; +} + +template +void println(const A &a, const B &b, const C &c, const D &d, const E &e, const F &f, const G &g) { + __testlib_print_one(a); + std::cout << " "; + __testlib_print_one(b); + std::cout << " "; + __testlib_print_one(c); + std::cout << " "; + __testlib_print_one(d); + std::cout << " "; + __testlib_print_one(e); + std::cout << " "; + __testlib_print_one(f); + std::cout << " "; + __testlib_print_one(g); + std::cout << std::endl; +} + +/* opts */ + +/** + * A struct for a singular testlib opt, containing the raw string value, + * and a boolean value for marking whether the opt is used. + */ +struct TestlibOpt { + std::string value; + bool used; + + TestlibOpt() : value(), used(false) {} +}; + +/** + * Get the type of opt based on the number of `-` at the beginning and the + * _validity_ of the key name. + * + * A valid key name must start with an alphabetical character. + * + * Returns: 1 if s has one `-` at the beginning, that is, "-keyName". + * 2 if s has two `-` at the beginning, that is, "--keyName". + * 0 otherwise. That is, if s has no `-` at the beginning, or has more + * than 2 at the beginning ("---keyName", "----keyName", ...), or the + * keyName is invalid (the first character is not an alphabetical + * character). + */ +size_t getOptType(char *s) { + if (!s || strlen(s) <= 1) + return 0; + + if (s[0] == '-') { + if (isalpha(s[1])) + return 1; + else if (s[1] == '-') + return isalpha(s[2]) ? 2 : 0; + } + + return 0; +} + +/** + * Parse the opt at a given index, and put it into the opts maps. + * + * An opt can has the following form: + * 1) -keyName=value or --keyName=value (ex. -n=10 --test-count=20) + * 2) -keyName value or --keyName value (ex. -n 10 --test-count 20) + * 3) -kNumval or --kNumval (ex. -n10 --t20) + * 4) -boolProperty or --boolProperty (ex. -sorted --tree-only) + * + * Only the second form consumes 2 arguments. The other consumes only 1 + * argument. + * + * In the third form, the key is a single character, and after the key is the + * value. The value _should_ be a number. + * + * In the forth form, the value is true. + * + * Params: + * - argc and argv: the number of command line arguments and the command line + * arguments themselves. + * - index: the starting index of the opts. + * - opts: the map containing the resulting opt. + * + * Returns: the number of consumed arguments to parse the opt. + * 0 if there is no arguments to parse. + * + * Algorithm details: + * TODO. Please refer to the implementation to see how the code handles the 3rd and 4th forms separately. + */ +size_t parseOpt(size_t argc, char *argv[], size_t index, std::map &opts) { + if (index >= argc) + return 0; + + size_t type = getOptType(argv[index]), inc = 1; + if (type > 0) { + std::string key(argv[index] + type), val; + size_t sep = key.find('='); + if (sep != std::string::npos) { + val = key.substr(sep + 1); + key = key.substr(0, sep); + } else { + if (index + 1 < argc && getOptType(argv[index + 1]) == 0) { + val = argv[index + 1]; + inc = 2; + } else { + if (key.length() > 1 && isdigit(key[1])) { + val = key.substr(1); + key = key.substr(0, 1); + } else { + val = "true"; + } + } + } + opts[key].value = val; + } else { + return inc; + } + + return inc; +} + +/** + * Global list containing all the arguments in the order given in the command line. + */ +std::vector __testlib_argv; + +/** + * Global dictionary containing all the parsed opts. + */ +std::map __testlib_opts; + +/** + * Whether automatic no unused opts ensurement should be done. This flag will + * be turned on when `has_opt` or `opt(key, default_value)` is called. + * + * The automatic ensurement can be suppressed when + * __testlib_ensureNoUnusedOptsSuppressed is true. + */ +bool __testlib_ensureNoUnusedOptsFlag = false; + +/** + * Suppress no unused opts automatic ensurement. Can be set to true with + * `suppressEnsureNoUnusedOpts()`. + */ +bool __testlib_ensureNoUnusedOptsSuppressed = false; + +/** + * Parse command line arguments into opts. + * The results are stored into __testlib_argv and __testlib_opts. + */ +void prepareOpts(int argc, char *argv[]) { + if (argc <= 0) + __testlib_fail("Opts: expected argc>=0 but found " + toString(argc)); + size_t n = static_cast(argc); // NOLINT(hicpp-use-auto,modernize-use-auto) + __testlib_opts = std::map(); + for (size_t index = 1; index < n; index += parseOpt(n, argv, index, __testlib_opts)); + __testlib_argv = std::vector(n); + for (size_t index = 0; index < n; index++) + __testlib_argv[index] = argv[index]; +} + +/** + * An utility function to get the argument with a given index. This function + * also print a readable message when no arguments are found. + */ +std::string __testlib_indexToArgv(int index) { + if (index < 0 || index >= int(__testlib_argv.size())) + __testlib_fail("Opts: index '" + toString(index) + "' is out of range [0," + + toString(__testlib_argv.size()) + ")"); + return __testlib_argv[size_t(index)]; +} + +/** + * An utility function to get the opt with a given key . This function + * also print a readable message when no opts are found. + */ +std::string __testlib_keyToOpts(const std::string &key) { + auto it = __testlib_opts.find(key); + if (it == __testlib_opts.end()) + __testlib_fail("Opts: unknown key '" + compress(key) + "'"); + it->second.used = true; + return it->second.value; +} + +template +T optValueToIntegral(const std::string &s, bool nonnegative); + +long double optValueToLongDouble(const std::string &s); + +std::string parseExponentialOptValue(const std::string &s) { + size_t pos = std::string::npos; + for (size_t i = 0; i < s.length(); i++) + if (s[i] == 'e' || s[i] == 'E') { + if (pos != std::string::npos) + __testlib_fail("Opts: expected typical exponential notation but '" + compress(s) + "' found"); + pos = i; + } + if (pos == std::string::npos) + return s; + std::string e = s.substr(pos + 1); + if (!e.empty() && e[0] == '+') + e = e.substr(1); + if (e.empty()) + __testlib_fail("Opts: expected typical exponential notation but '" + compress(s) + "' found"); + if (e.length() > 20) + __testlib_fail("Opts: expected typical exponential notation but '" + compress(s) + "' found"); + int ne = optValueToIntegral(e, false); + std::string num = s.substr(0, pos); + if (num.length() > 20) + __testlib_fail("Opts: expected typical exponential notation but '" + compress(s) + "' found"); + if (!num.empty() && num[0] == '+') + num = num.substr(1); + optValueToLongDouble(num); + bool minus = false; + if (num[0] == '-') { + minus = true; + num = num.substr(1); + } + for (int i = 0; i < +ne; i++) { + size_t sep = num.find('.'); + if (sep == std::string::npos) + num += '0'; + else { + if (sep + 1 == num.length()) + num[sep] = '0'; + else + std::swap(num[sep], num[sep + 1]); + } + } + for (int i = 0; i < -ne; i++) { + size_t sep = num.find('.'); + if (sep == std::string::npos) + num.insert(num.begin() + int(num.length()) - 1, '.'); + else { + if (sep == 0) + num.insert(num.begin() + 1, '0'); + else + std::swap(num[sep - 1], num[sep]); + } + } + while (!num.empty() && num[0] == '0') + num = num.substr(1); + while (num.find('.') != std::string::npos && num.back() == '0') + num = num.substr(0, num.length() - 1); + if (!num.empty() && num.back() == '.') + num = num.substr(0, num.length() - 1); + if ((!num.empty() && num[0] == '.') || num.empty()) + num.insert(num.begin(), '0'); + return (minus ? "-" : "") + num; +} + +template +T optValueToIntegral(const std::string &s_, bool nonnegative) { + std::string s(parseExponentialOptValue(s_)); + if (s.empty()) + __testlib_fail("Opts: expected integer but '" + compress(s_) + "' found"); + T value = 0; + long double about = 0.0; + signed char sign = +1; + size_t pos = 0; + if (s[pos] == '-') { + if (nonnegative) + __testlib_fail("Opts: expected non-negative integer but '" + compress(s_) + "' found"); + sign = -1; + pos++; + } + for (size_t i = pos; i < s.length(); i++) { + if (s[i] < '0' || s[i] > '9') + __testlib_fail("Opts: expected integer but '" + compress(s_) + "' found"); + value = value * 10 + s[i] - '0'; + about = about * 10 + s[i] - '0'; + } + value *= sign; + about *= sign; + if (fabsl(value - about) > 0.1) + __testlib_fail("Opts: integer overflow: expected integer but '" + compress(s_) + "' found"); + return value; +} + +long double optValueToLongDouble(const std::string &s_) { + std::string s(parseExponentialOptValue(s_)); + if (s.empty()) + __testlib_fail("Opts: expected float number but '" + compress(s_) + "' found"); + long double value = 0.0; + signed char sign = +1; + size_t pos = 0; + if (s[pos] == '-') { + sign = -1; + pos++; + } + bool period = false; + long double mul = 1.0; + for (size_t i = pos; i < s.length(); i++) { + if (s[i] == '.') { + if (period) + __testlib_fail("Opts: expected float number but '" + compress(s_) + "' found"); + else { + period = true; + continue; + } + } + if (period) + mul *= 10.0; + if (s[i] < '0' || s[i] > '9') + __testlib_fail("Opts: expected float number but '" + compress(s_) + "' found"); + if (period) + value += (s[i] - '0') / mul; + else + value = value * 10 + s[i] - '0'; + } + value *= sign; + return value; +} + +/** + * Return true if there is an opt with a given key. + * + * By calling this function, automatic ensurement for no unused opts will be + * done when the program is finalized. Call suppressEnsureNoUnusedOpts() to + * turn it off. + */ +bool has_opt(const std::string &key) { + __testlib_ensureNoUnusedOptsFlag = true; + return __testlib_opts.count(key) != 0; +} + +/* About the followings part for opt with 2 and 3 arguments. + * + * To parse the argv/opts correctly for a give type (integer, floating point or + * string), some meta programming must be done to determine the type of + * the type, and use the correct parsing function accordingly. + * + * The pseudo algorithm for determining the type of T and parse it accordingly + * is as follows: + * + * if (T is integral type) { + * if (T is unsigned) { + * parse the argv/opt as an **unsigned integer** of type T. + * } else { + * parse the argv/opt as an **signed integer** of type T. + * } else { + * if (T is floating point type) { + * parse the argv/opt as an **floating point** of type T. + * } else { + * // T should be std::string + * just the raw content of the argv/opts. + * } + * } + * + * To help with meta programming, some `opt` function with 2 or 3 arguments are + * defined. + * + * Opt with 3 arguments: T opt(true/false is_integral, true/false is_unsigned, index/key) + * + * + The first argument is for determining whether the type T is an integral + * type. That is, the result of std::is_integral() should be passed to + * this argument. When false, the type _should_ be either floating point or a + * std::string. + * + * + The second argument is for determining whether the signedness of the type + * T (if it is unsigned or signed). That is, the result of + * std::is_unsigned() should be passed to this argument. This argument can + * be ignored if the first one is false, because it only applies to integer. + * + * Opt with 2 arguments: T opt(true/false is_floating_point, index/key) + * + The first argument is for determining whether the type T is a floating + * point type. That is, the result of std::is_floating_point() should be + * passed to this argument. When false, the type _should_ be a std::string. + */ + +template +T opt(std::false_type is_floating_point, int index); + +template<> +std::string opt(std::false_type /*is_floating_point*/, int index) { + return __testlib_indexToArgv(index); +} + +template +T opt(std::true_type /*is_floating_point*/, int index) { + return T(optValueToLongDouble(__testlib_indexToArgv(index))); +} + +template +T opt(std::false_type /*is_integral*/, U /*is_unsigned*/, int index) { + return opt(std::is_floating_point(), index); +} + +template +T opt(std::true_type /*is_integral*/, std::false_type /*is_unsigned*/, int index) { + return optValueToIntegral(__testlib_indexToArgv(index), false); +} + +template +T opt(std::true_type /*is_integral*/, std::true_type /*is_unsigned*/, int index) { + return optValueToIntegral(__testlib_indexToArgv(index), true); +} + +template<> +bool opt(std::true_type /*is_integral*/, std::true_type /*is_unsigned*/, int index) { + std::string value = __testlib_indexToArgv(index); + if (value == "true" || value == "1") + return true; + if (value == "false" || value == "0") + return false; + __testlib_fail("Opts: opt by index '" + toString(index) + "': expected bool true/false or 0/1 but '" + + compress(value) + "' found"); +} + +/** + * Return the parsed argv by a given index. + */ +template +T opt(int index) { + return opt(std::is_integral(), std::is_unsigned(), index); +} + +/** + * Return the raw string value of an argv by a given index. + */ +std::string opt(int index) { + return opt(index); +} + +/** + * Return the parsed argv by a given index. If the index is bigger than + * the number of argv, return the given default_value. + */ +template +T opt(int index, const T &default_value) { + if (index >= int(__testlib_argv.size())) { + return default_value; + } + return opt(index); +} + +/** + * Return the raw string value of an argv by a given index. If the index is + * bigger than the number of argv, return the given default_value. + */ +std::string opt(int index, const std::string &default_value) { + return opt(index, default_value); +} + +template +T opt(std::false_type is_floating_point, const std::string &key); + +template<> +std::string opt(std::false_type /*is_floating_point*/, const std::string &key) { + return __testlib_keyToOpts(key); +} + +template +T opt(std::true_type /*is_integral*/, const std::string &key) { + return T(optValueToLongDouble(__testlib_keyToOpts(key))); +} + +template +T opt(std::false_type /*is_integral*/, U, const std::string &key) { + return opt(std::is_floating_point(), key); +} + +template +T opt(std::true_type /*is_integral*/, std::false_type /*is_unsigned*/, const std::string &key) { + return optValueToIntegral(__testlib_keyToOpts(key), false); +} + +template +T opt(std::true_type /*is_integral*/, std::true_type /*is_unsigned*/, const std::string &key) { + return optValueToIntegral(__testlib_keyToOpts(key), true); +} + +template<> +bool opt(std::true_type /*is_integral*/, std::true_type /*is_unsigned*/, const std::string &key) { + if (!has_opt(key)) + return false; + std::string value = __testlib_keyToOpts(key); + if (value == "true" || value == "1") + return true; + if (value == "false" || value == "0") + return false; + __testlib_fail("Opts: key '" + compress(key) + "': expected bool true/false or 0/1 but '" + + compress(value) + "' found"); +} + +/** + * Return the parsed opt by a given key. + */ +template +T opt(const std::string &key) { + return opt(std::is_integral(), std::is_unsigned(), key); +} + +/** + * Return the raw string value of an opt by a given key + */ +std::string opt(const std::string &key) { + return opt(key); +} + +/* Scorer started. */ + +enum TestResultVerdict { + SKIPPED, + OK, + WRONG_ANSWER, + RUNTIME_ERROR, + TIME_LIMIT_EXCEEDED, + IDLENESS_LIMIT_EXCEEDED, + MEMORY_LIMIT_EXCEEDED, + COMPILATION_ERROR, + CRASHED, + FAILED +}; + +std::string serializeVerdict(TestResultVerdict verdict) { + switch (verdict) { + case SKIPPED: return "SKIPPED"; + case OK: return "OK"; + case WRONG_ANSWER: return "WRONG_ANSWER"; + case RUNTIME_ERROR: return "RUNTIME_ERROR"; + case TIME_LIMIT_EXCEEDED: return "TIME_LIMIT_EXCEEDED"; + case IDLENESS_LIMIT_EXCEEDED: return "IDLENESS_LIMIT_EXCEEDED"; + case MEMORY_LIMIT_EXCEEDED: return "MEMORY_LIMIT_EXCEEDED"; + case COMPILATION_ERROR: return "COMPILATION_ERROR"; + case CRASHED: return "CRASHED"; + case FAILED: return "FAILED"; + } + throw "Unexpected verdict"; +} + +TestResultVerdict deserializeTestResultVerdict(std::string s) { + if (s == "SKIPPED") + return SKIPPED; + else if (s == "OK") + return OK; + else if (s == "WRONG_ANSWER") + return WRONG_ANSWER; + else if (s == "RUNTIME_ERROR") + return RUNTIME_ERROR; + else if (s == "TIME_LIMIT_EXCEEDED") + return TIME_LIMIT_EXCEEDED; + else if (s == "IDLENESS_LIMIT_EXCEEDED") + return IDLENESS_LIMIT_EXCEEDED; + else if (s == "MEMORY_LIMIT_EXCEEDED") + return MEMORY_LIMIT_EXCEEDED; + else if (s == "COMPILATION_ERROR") + return COMPILATION_ERROR; + else if (s == "CRASHED") + return CRASHED; + else if (s == "FAILED") + return FAILED; + ensuref(false, "Unexpected serialized TestResultVerdict"); + // No return actually. + return FAILED; +} + +struct TestResult { + int testIndex; + std::string testset; + std::string group; + TestResultVerdict verdict; + double points; + long long timeConsumed; + long long memoryConsumed; + std::string input; + std::string output; + std::string answer; + int exitCode; + std::string checkerComment; +}; + +std::string serializePoints(double points) { + if (std::isnan(points)) + return ""; + else { + char c[64]; + sprintf(c, "%.03lf", points); + return c; + } +} + +double deserializePoints(std::string s) { + if (s.empty()) + return std::numeric_limits::quiet_NaN(); + else { + double result; + ensuref(sscanf(s.c_str(), "%lf", &result) == 1, "Invalid serialized points"); + return result; + } +} + +std::string escapeTestResultString(std::string s) { + std::string result; + for (size_t i = 0; i < s.length(); i++) { + if (s[i] == '\r') + continue; + if (s[i] == '\n') { + result += "\\n"; + continue; + } + if (s[i] == '\\' || s[i] == ';') + result += '\\'; + result += s[i]; + } + return result; +} + +std::string unescapeTestResultString(std::string s) { + std::string result; + for (size_t i = 0; i < s.length(); i++) { + if (s[i] == '\\' && i + 1 < s.length()) { + if (s[i + 1] == 'n') { + result += '\n'; + i++; + continue; + } else if (s[i + 1] == ';' || s[i + 1] == '\\') { + result += s[i + 1]; + i++; + continue; + } + } + result += s[i]; + } + return result; +} + +std::string serializeTestResult(TestResult tr) { + std::string result; + result += std::to_string(tr.testIndex); + result += ";"; + result += escapeTestResultString(tr.testset); + result += ";"; + result += escapeTestResultString(tr.group); + result += ";"; + result += serializeVerdict(tr.verdict); + result += ";"; + result += serializePoints(tr.points); + result += ";"; + result += std::to_string(tr.timeConsumed); + result += ";"; + result += std::to_string(tr.memoryConsumed); + result += ";"; + result += escapeTestResultString(tr.input); + result += ";"; + result += escapeTestResultString(tr.output); + result += ";"; + result += escapeTestResultString(tr.answer); + result += ";"; + result += std::to_string(tr.exitCode); + result += ";"; + result += escapeTestResultString(tr.checkerComment); + return result; +} + +TestResult deserializeTestResult(std::string s) { + std::vector items; + std::string t; + for (size_t i = 0; i < s.length(); i++) { + if (s[i] == '\\') { + t += s[i]; + if (i + 1 < s.length()) + t += s[i + 1]; + i++; + continue; + } else { + if (s[i] == ';') { + items.push_back(t); + t = ""; + } else + t += s[i]; + } + } + items.push_back(t); + + ensuref(items.size() == 12, "Invalid TestResult serialization: expected exactly 12 items"); + + TestResult tr; + size_t pos = 0; + tr.testIndex = stoi(items[pos++]); + tr.testset = unescapeTestResultString(items[pos++]); + tr.group = unescapeTestResultString(items[pos++]); + tr.verdict = deserializeTestResultVerdict(items[pos++]); + tr.points = deserializePoints(items[pos++]); + tr.timeConsumed = stoll(items[pos++]); + tr.memoryConsumed = stoll(items[pos++]); + tr.input = unescapeTestResultString(items[pos++]); + tr.output = unescapeTestResultString(items[pos++]); + tr.answer = unescapeTestResultString(items[pos++]); + tr.exitCode = stoi(items[pos++]); + tr.checkerComment = unescapeTestResultString(items[pos++]); + + return tr; +} + +std::vector readTestResults(std::string fileName) { + std::ifstream stream; + stream.open(fileName.c_str(), std::ios::in); + ensuref(stream.is_open(), "Can't read test results file '%s'", fileName.c_str()); + std::vector result; + std::string line; + while (getline(stream, line)) + if (!line.empty()) + result.push_back(deserializeTestResult(line)); + stream.close(); + return result; +} + +std::function)> __testlib_scorer; + +struct TestlibScorerGuard { + ~TestlibScorerGuard() { + if (testlibMode == _scorer) { + std::vector testResults; + while (!inf.eof()) { + std::string line = inf.readLine(); + if (!line.empty()) + testResults.push_back(deserializeTestResult(line)); + } + inf.readEof(); + printf("%.3f\n", __testlib_scorer(testResults)); + } + } +} __testlib_scorer_guard; + +void registerScorer(int argc, char *argv[], std::function)> scorer) { + /* Supress unused. */ + (void)(argc), (void)(argv); + + __testlib_ensuresPreconditions(); + + testlibMode = _scorer; + __testlib_set_binary(stdin); + + inf.init(stdin, _input); + inf.strict = false; + + __testlib_scorer = scorer; +} + +/* Scorer ended. */ + +/** + * Return the parsed opt by a given key. If no opts with the given key are + * found, return the given default_value. + * + * By calling this function, automatic ensurement for no unused opts will be + * done when the program is finalized. Call suppressEnsureNoUnusedOpts() to + * turn it off. + */ +template +T opt(const std::string &key, const T &default_value) { + if (!has_opt(key)) { + return default_value; + } + return opt(key); +} + +/** + * Return the raw string value of an opt by a given key. If no opts with the + * given key are found, return the given default_value. + * + * By calling this function, automatic ensurement for no unused opts will be + * done when the program is finalized. Call suppressEnsureNoUnusedOpts() to + * turn it off. + */ +std::string opt(const std::string &key, const std::string &default_value) { + return opt(key, default_value); +} + +/** + * Check if all opts are used. If not, __testlib_fail is called. + * Should be used after calling all opt() function calls. + * + * This function is useful when opt() with default_value for checking typos + * in the opt's key. + */ +void ensureNoUnusedOpts() { + for (const auto &opt: __testlib_opts) { + if (!opt.second.used) { + __testlib_fail(format("Opts: unused key '%s'", compress(opt.first).c_str())); + } + } +} + +void suppressEnsureNoUnusedOpts() { + __testlib_ensureNoUnusedOptsSuppressed = true; +} + +void TestlibFinalizeGuard::autoEnsureNoUnusedOpts() { + if (__testlib_ensureNoUnusedOptsFlag && !__testlib_ensureNoUnusedOptsSuppressed) { + ensureNoUnusedOpts(); + } +} + +TestlibFinalizeGuard testlibFinalizeGuard; + +#endif +#endif diff --git a/ra-preguicosa/src/validator.cpp b/ra-preguicosa/src/validator.cpp new file mode 100644 index 0000000..1b212e4 --- /dev/null +++ b/ra-preguicosa/src/validator.cpp @@ -0,0 +1,44 @@ +#include "testlib.h" +#include + +using namespace std; + + +int main(int argc, char* argv[]) { + registerValidation(argc, argv); + while (true) { + int C = inf.readInt(1, 1000, "C"); + inf.readSpace(); + int R = inf.readInt(1, 1000, "R"); + inf.readEoln(); + if (C == 0 && R == 0) break; + + int Cf, Rf, Ct, Rt; + Cf = inf.readInt(1, C, "Cf"); + inf.readSpace(); + Rf = inf.readInt(1, R, "Rf"); + inf.readSpace(); + Ct = inf.readInt(1, C, "Ct"); + inf.readSpace(); + Rt = inf.readInt(1, R, "Rt"); + inf.readEoln(); + + int W = inf.readInt(0, 1000, "W"); + inf.readEoln(); + + for (int i = 0; i < W; i++) { + int C1, C2, R1, R2; + C1 = inf.readInt(1, C, "C1"); + inf.readSpace(); + C2 = inf.readInt(1, C, "C2"); + inf.readSpace(); + R1 = inf.readInt(1, R, "R1"); + inf.readSpace(); + R2 = inf.readInt(1, R, "R2"); + inf.readEoln(); + } + + } + inf.readEof(); + return 0; +} \ No newline at end of file diff --git a/ra-preguicosa/statement/description.tex b/ra-preguicosa/statement/description.tex new file mode 100644 index 0000000..fadb27a --- /dev/null +++ b/ra-preguicosa/statement/description.tex @@ -0,0 +1,5 @@ +Sr. Rã vive em um pântano em forma de grade retangular, composto de células de mesmo tamanho, algumas delas são secas, outras são somente lugares alagados. Sr. Rã vive em uma célula seca e pode saltar somente de uma célula seca para outra célula seca em seus passeios pelo pântano. + +Sr. Rã quer visitar sua namorada, Sra. Sapo, que também vive em uma célula seca no mesmo pântano. Mas Sr. Rã é preguiçoso, e quer gastar a menor quantidade de energia em seu caminho "saltante" até a casa da Sra. Sapo. Sr. Rã sabe quanta energia gasta em qualquer um de seus saltos. Para cada salto simples, Sr. Rã usa a figura a seguir para determinar quais são as possíveis células alvo de sua posição atual (a celula marcada com F), e a quantidade de energia correspondente no salto, em calorias. Qualquer outra célula é inatíngivel da posição atual de Sr. Rã com um salto simples. + +Sua tarefa é determinar a quantidade minima de energia que Sr. Rã precisa gastar para ir de sua casa para a casa da Sra. Sapo. \ No newline at end of file diff --git a/ra-preguicosa/statement/input.tex b/ra-preguicosa/statement/input.tex new file mode 100644 index 0000000..53c443c --- /dev/null +++ b/ra-preguicosa/statement/input.tex @@ -0,0 +1,6 @@ +A entrada contém varios casos de teste. +A primeira linha de um caso de teste contém dois inteiros, $C$ e $R$, indicando respectivamente o numero de colunas e linhas do pântano ($1 \le C, R \le 1000$). +A segunda linha de um caso de teste contem quatro inteiros $C_f$, $R_f$, $C_t$, e $R_t$, onde $(C_f, R_f)$ especifica a localização da casa do Sr. Rã e $(C_t, R_t)$ especifica a localização da casa da Sra. Sapo. +A terceira linha de um caso de teste contém um inteiro $W$ ($0 \le W \le 1000$) indicando o número de lugares alagados no pântano. +Cada uma das próximas $W$ linhas contém quatro inteiros $C_1$, $R_1$, $C_2$, e $R_2$ ($1 \le C_1 \le C_2 \le C$ e $1 \le R_1 \le R_2 \le R$) descrevendo um lugar retangular alagado contendo células cujas coordenadas $(x,y)$ são tais que $C_1 \le x \le C_2$ e $R_1 \le y \le R_2$. +O fim da entrada é indicado por $C=R=0$. \ No newline at end of file diff --git a/ra-preguicosa/statement/notes.tex b/ra-preguicosa/statement/notes.tex new file mode 100644 index 0000000..e69de29 diff --git a/ra-preguicosa/statement/output.tex b/ra-preguicosa/statement/output.tex new file mode 100644 index 0000000..995cd0e --- /dev/null +++ b/ra-preguicosa/statement/output.tex @@ -0,0 +1,2 @@ +Para cada caso de teste na entrada, seu programa deve produzir uma linha de saída, contendo o mínimo de calorias consumidas pelo Sr. Rã para ir de sua casa para a casa da Sra. Sapo. +Se não houver como o Sr. Rã chegar até a casa da Sra. Sapo, seu programa deve imprimir 'impossible'. \ No newline at end of file diff --git a/ra-preguicosa/statement/preamble.tex b/ra-preguicosa/statement/preamble.tex new file mode 100644 index 0000000..e69de29 diff --git a/ra-preguicosa/statement/tutorial.tex b/ra-preguicosa/statement/tutorial.tex new file mode 100644 index 0000000..e69de29 From 3cfeb9a032380e54cecb6102132f581f99f623c2 Mon Sep 17 00:00:00 2001 From: arthur Date: Sat, 2 May 2026 12:34:17 -0300 Subject: [PATCH 2/3] feat: new solution code. --- ra-preguicosa/src/ac.cpp | 122 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/ra-preguicosa/src/ac.cpp b/ra-preguicosa/src/ac.cpp index 0b2cb0b..6260937 100644 --- a/ra-preguicosa/src/ac.cpp +++ b/ra-preguicosa/src/ac.cpp @@ -1,8 +1,128 @@ #include +#define endl '\n' +#define INF 0x3f + using namespace std; +typedef pair pii; -int main(){ +const int MAXN = 1e3 + 10; + +int C, L, W; +int Cr, Lr, Cs, Ls; +int alagado[MAXN][MAXN]; +const int COSTS[5][5] = { + {7, 6, 5, 6, 7}, + {6, 3, 2, 3, 6}, + {5, 2, 0, 2, 5}, + {6, 3, 2, 3, 6}, + {7, 6, 5, 6, 7}, +}; +int vis[MAXN][MAXN]; +int g[MAXN][MAXN]; + +bool valid(int c, int l) { + return c > 0 && c <= C && l > 0 && l <= L && alagado[c][l] == 0; +} + +int h(int c, int l) +{ + return sqrt(abs(Cs - c)*abs(Cs - c) + abs(Ls - l)*abs(Ls - l)); +} + +bool reachable() +{ + queue q; + memset(vis, 0, sizeof(vis)); + + q.push({Cr, Lr}); + vis[Cr][Lr] = 1; + + while (!q.empty()) + { + auto [c, l] = q.front(); + q.pop(); + + if (c == Cs && l == Ls) return true; + + for (int i = -2; i <= 2; i++){ + for (int j = -2; j <= 2; j++){ + int nc = c + i, nl = l + j; + if (!valid(nc, nl) || vis[nc][nl]) continue; + vis[nc][nl] = 1; + q.push({nc, nl}); + } + } + } + + return false; +} + +void solve() +{ + if (!reachable()) + { + cout << "impossible" << endl; + return; + } + + memset(vis, 0, sizeof(vis)); + memset(g, INF, sizeof(g)); + priority_queue> pq; + g[Cr][Lr] = 0; + pq.push({-h(Cr, Lr), {Cr, Lr}}); + while (!pq.empty()){ + auto [curCost, curCoords] = pq.top(); + pq.pop(); + + auto [c, l] = curCoords; + + if (vis[c][l]) continue; + vis[c][l] = 1; + + if (c == Cs && l == Ls){ + cout << g[c][l] << endl; + return; + } + + for (int i = -2; i <= 2; i++){ + for (int j = -2; j <= 2; j++){ + int nc = c + i, nl = l + j; + if (!valid(nc, nl)) continue; + + int cost = COSTS[i + 2][j + 2]; + int newG = g[c][l] + cost; + if (newG < g[nc][nl]){ + g[nc][nl] = newG; + int f = g[nc][nl] + h(nc, nl); + // insere custo negativo pois por padrao a priority queue é uma max heap + pq.push({-f, {nc, nl}}); + } + } + } + } +} + +int main() +{ + ios::sync_with_stdio(false); + cin.tie(nullptr); + + while (cin >> C >> L, C && L){ + cin >> Cr >> Lr; + cin >> Cs >> Ls; + cin >> W; + memset(alagado, 0, sizeof(alagado)); + memset(vis, 0, sizeof(vis)); + for (int i = 0; i < W; i++){ + int C1, C2, L1, L2; + cin >> C1 >> L1 >> C2 >> L2; + for (int k = C1; k <= C2; k++) + for (int l = L1; l <= L2; l++) + alagado[k][l] = 1; + } + solve(); + } return 0; } \ No newline at end of file From cec770f1f6234e9e9084bb2cb25f710f7290e50a Mon Sep 17 00:00:00 2001 From: arthur Date: Sat, 2 May 2026 12:53:43 -0300 Subject: [PATCH 3/3] fix: fixed validator and added input file and checker. --- ra-preguicosa/input/1 | 8053 +++++++++++++++++++++++++++++++ ra-preguicosa/output/1 | 45 + ra-preguicosa/problem.json | 4 +- ra-preguicosa/ra-preguicosa.pdf | Bin 0 -> 29320 bytes ra-preguicosa/ra-preguicosa.tex | 13 + ra-preguicosa/src/checker.cpp | 33 +- ra-preguicosa/src/validator.cpp | 13 +- 7 files changed, 8148 insertions(+), 13 deletions(-) create mode 100644 ra-preguicosa/input/1 create mode 100644 ra-preguicosa/output/1 create mode 100644 ra-preguicosa/ra-preguicosa.pdf create mode 100644 ra-preguicosa/ra-preguicosa.tex diff --git a/ra-preguicosa/input/1 b/ra-preguicosa/input/1 new file mode 100644 index 0000000..d938028 --- /dev/null +++ b/ra-preguicosa/input/1 @@ -0,0 +1,8053 @@ +5 5 +5 5 5 5 +2 +1 1 4 5 +5 1 5 4 +10 10 +5 5 10 10 +4 +3 3 7 4 +3 6 7 7 +3 5 4 5 +6 5 7 5 +4 4 +1 1 4 2 +2 +2 1 3 3 +4 3 4 4 +4 4 +1 1 4 2 +1 +2 1 3 4 +7 6 +4 2 7 6 +5 +4 1 7 1 +5 1 5 5 +2 4 3 4 +7 5 7 5 +6 6 6 6 +10 10 +1 1 5 5 +8 +2 2 9 2 +2 9 9 9 +2 3 2 8 +9 3 9 8 +4 4 7 4 +4 7 7 7 +4 5 4 6 +7 5 7 6 +10 10 +5 5 10 10 +8 +2 2 9 2 +2 9 9 9 +2 3 2 8 +9 3 9 8 +4 4 7 4 +4 7 7 7 +4 5 4 6 +7 5 7 6 +20 20 +1 1 10 10 +12 +2 2 19 2 +2 19 19 19 +2 3 2 18 +19 3 19 18 +4 4 17 4 +4 17 17 17 +4 5 4 16 +17 5 17 16 +6 6 15 6 +6 15 15 15 +6 7 6 14 +15 7 15 14 +20 20 +1 1 10 10 +8 +2 2 19 3 +2 18 19 19 +2 4 3 17 +18 4 19 17 +5 5 16 6 +5 15 16 16 +5 7 6 14 +15 7 16 14 +10 10 +1 1 10 10 +50 +4 7 4 7 +4 5 4 5 +4 3 4 3 +2 7 2 7 +4 1 4 1 +5 6 5 6 +1 6 1 6 +5 4 5 4 +5 2 5 2 +4 9 4 9 +9 2 9 2 +2 3 2 3 +2 5 2 5 +1 4 1 4 +9 4 9 4 +2 9 2 9 +9 10 9 10 +3 2 3 2 +3 4 3 4 +9 8 9 8 +3 6 3 6 +1 8 1 8 +5 8 5 8 +10 9 10 9 +1 2 1 2 +8 1 8 1 +10 3 10 3 +10 1 10 1 +6 5 6 5 +6 7 6 7 +6 1 6 1 +6 3 6 3 +7 4 7 4 +7 8 7 8 +7 6 7 6 +8 7 8 7 +6 9 6 9 +7 2 7 2 +1 10 1 10 +8 9 8 9 +3 8 3 8 +7 10 7 10 +5 10 5 10 +2 1 2 1 +10 7 10 7 +8 3 8 3 +8 5 8 5 +9 6 9 6 +3 10 3 10 +10 5 10 5 +5 5 +1 1 5 5 +12 +4 5 4 5 +4 3 4 3 +4 1 4 1 +1 2 1 2 +5 4 5 4 +5 2 5 2 +1 4 1 4 +2 1 2 1 +2 3 2 3 +2 5 2 5 +3 2 3 2 +3 4 3 4 +20 20 +19 19 1 1 +200 +4 7 4 7 +18 13 18 13 +4 5 4 5 +4 3 4 3 +4 1 4 1 +19 20 19 20 +4 9 4 9 +2 1 2 1 +17 2 17 2 +2 5 2 5 +2 7 2 7 +17 8 17 8 +18 17 18 17 +11 16 11 16 +11 10 11 10 +11 12 11 12 +5 8 5 8 +13 4 13 4 +8 17 8 17 +13 6 13 6 +13 2 13 2 +12 9 12 9 +8 15 8 15 +13 8 13 8 +15 8 15 8 +10 19 10 19 +10 13 10 13 +8 13 8 13 +10 11 10 11 +10 17 10 17 +9 20 9 20 +10 15 10 15 +7 18 7 18 +5 10 5 10 +6 9 6 9 +2 3 2 3 +1 20 1 20 +17 4 17 4 +14 17 14 17 +14 9 14 9 +17 6 17 6 +14 3 14 3 +14 1 14 1 +14 7 14 7 +14 5 14 5 +9 2 9 2 +2 9 2 9 +5 12 5 12 +9 6 9 6 +9 4 9 4 +9 8 9 8 +14 15 14 15 +10 9 10 9 +10 7 10 7 +12 11 12 11 +10 5 10 5 +10 3 10 3 +10 1 10 1 +7 8 7 8 +14 11 14 11 +5 16 5 16 +7 4 7 4 +7 6 7 6 +7 2 7 2 +12 17 12 17 +2 19 2 19 +2 15 2 15 +2 17 2 17 +2 11 2 11 +1 8 1 8 +2 13 2 13 +6 11 6 11 +6 13 6 13 +13 20 13 20 +6 15 6 15 +6 17 6 17 +6 19 6 19 +5 20 5 20 +15 10 15 10 +15 12 15 12 +13 12 13 12 +13 10 13 10 +15 18 15 18 +13 18 13 18 +14 13 14 13 +15 2 15 2 +18 11 18 11 +15 6 15 6 +15 4 15 4 +5 6 5 6 +5 4 5 4 +5 2 5 2 +8 11 8 11 +3 8 3 8 +12 19 12 19 +11 8 11 8 +14 19 14 19 +12 15 12 15 +3 2 3 2 +12 13 12 13 +3 4 3 4 +3 6 3 6 +11 6 11 6 +20 11 20 11 +11 4 11 4 +20 13 20 13 +11 2 11 2 +20 15 20 15 +11 14 11 14 +20 17 20 17 +1 2 1 2 +20 19 20 19 +1 6 1 6 +1 4 1 4 +19 14 19 14 +19 16 19 16 +19 10 19 10 +19 12 19 12 +19 18 19 18 +13 16 13 16 +17 18 17 18 +7 20 7 20 +1 18 1 18 +5 18 5 18 +17 12 17 12 +9 18 9 18 +17 10 17 10 +1 10 1 10 +13 14 13 14 +1 12 1 12 +18 15 18 15 +11 20 11 20 +15 20 15 20 +15 14 15 14 +16 9 16 9 +15 16 15 16 +19 8 19 8 +19 6 19 6 +19 4 19 4 +19 2 19 2 +4 19 4 19 +4 13 4 13 +7 14 7 14 +4 11 4 11 +4 17 4 17 +4 15 4 15 +9 14 9 14 +9 16 9 16 +9 10 9 10 +9 12 9 12 +7 16 7 16 +5 14 5 14 +7 12 7 12 +7 10 7 10 +18 7 18 7 +18 5 18 5 +18 3 18 3 +18 1 18 1 +16 1 16 1 +11 18 11 18 +16 3 16 3 +16 5 16 5 +16 7 16 7 +8 9 8 9 +8 3 8 3 +8 1 8 1 +8 7 8 7 +8 5 8 5 +6 5 6 5 +1 14 1 14 +6 7 6 7 +6 1 6 1 +18 9 18 9 +6 3 6 3 +12 5 12 5 +12 7 12 7 +12 1 12 1 +1 16 1 16 +12 3 12 3 +3 20 3 20 +20 3 20 3 +8 19 8 19 +20 1 20 1 +20 7 20 7 +20 5 20 5 +17 16 17 16 +18 19 18 19 +20 9 20 9 +17 14 17 14 +16 11 16 11 +16 13 16 13 +16 15 16 15 +16 17 16 17 +16 19 16 19 +3 18 3 18 +17 20 17 20 +3 12 3 12 +3 10 3 10 +3 16 3 16 +3 14 3 14 +20 20 +1 1 20 20 +200 +4 7 4 7 +18 13 18 13 +4 5 4 5 +4 3 4 3 +4 1 4 1 +19 20 19 20 +4 9 4 9 +2 1 2 1 +17 2 17 2 +2 5 2 5 +2 7 2 7 +17 8 17 8 +18 17 18 17 +11 16 11 16 +11 10 11 10 +11 12 11 12 +5 8 5 8 +13 4 13 4 +8 17 8 17 +13 6 13 6 +13 2 13 2 +12 9 12 9 +8 15 8 15 +13 8 13 8 +15 8 15 8 +10 19 10 19 +10 13 10 13 +8 13 8 13 +10 11 10 11 +10 17 10 17 +9 20 9 20 +10 15 10 15 +7 18 7 18 +5 10 5 10 +6 9 6 9 +2 3 2 3 +1 20 1 20 +14 17 14 17 +14 9 14 9 +17 6 17 6 +14 3 14 3 +14 1 14 1 +14 7 14 7 +14 5 14 5 +9 2 9 2 +2 9 2 9 +5 12 5 12 +9 6 9 6 +9 4 9 4 +9 8 9 8 +14 15 14 15 +10 9 10 9 +10 7 10 7 +12 11 12 11 +10 5 10 5 +10 3 10 3 +10 1 10 1 +7 8 7 8 +14 11 14 11 +5 16 5 16 +7 4 7 4 +7 6 7 6 +7 2 7 2 +12 17 12 17 +2 19 2 19 +2 15 2 15 +2 17 2 17 +2 11 2 11 +1 8 1 8 +2 13 2 13 +6 11 6 11 +6 13 6 13 +13 20 13 20 +6 15 6 15 +6 17 6 17 +6 19 6 19 +5 20 5 20 +15 10 15 10 +15 12 15 12 +13 12 13 12 +13 10 13 10 +15 18 15 18 +13 18 13 18 +4 15 4 15 +14 13 14 13 +15 2 15 2 +18 11 18 11 +15 6 15 6 +15 4 15 4 +5 6 5 6 +5 4 5 4 +5 2 5 2 +8 11 8 11 +3 8 3 8 +12 19 12 19 +11 8 11 8 +14 19 14 19 +12 15 12 15 +3 2 3 2 +12 13 12 13 +3 4 3 4 +3 6 3 6 +11 6 11 6 +20 11 20 11 +11 4 11 4 +20 13 20 13 +11 2 11 2 +20 15 20 15 +11 14 11 14 +20 17 20 17 +1 2 1 2 +20 19 20 19 +1 6 1 6 +1 4 1 4 +19 14 19 14 +19 16 19 16 +19 10 19 10 +19 12 19 12 +19 18 19 18 +7 14 7 14 +13 16 13 16 +17 18 17 18 +7 20 7 20 +1 18 1 18 +5 18 5 18 +17 12 17 12 +9 18 9 18 +17 10 17 10 +1 10 1 10 +13 14 13 14 +1 12 1 12 +18 15 18 15 +11 20 11 20 +15 20 15 20 +15 14 15 14 +16 9 16 9 +15 16 15 16 +19 8 19 8 +19 6 19 6 +19 4 19 4 +19 2 19 2 +4 19 4 19 +4 13 4 13 +4 11 4 11 +4 17 4 17 +17 4 17 4 +9 14 9 14 +9 16 9 16 +9 10 9 10 +9 12 9 12 +7 16 7 16 +5 14 5 14 +7 12 7 12 +7 10 7 10 +18 7 18 7 +18 5 18 5 +18 3 18 3 +18 1 18 1 +16 1 16 1 +11 18 11 18 +16 3 16 3 +16 5 16 5 +16 7 16 7 +8 9 8 9 +8 3 8 3 +8 1 8 1 +8 7 8 7 +8 5 8 5 +6 5 6 5 +1 14 1 14 +6 7 6 7 +6 1 6 1 +18 9 18 9 +6 3 6 3 +12 5 12 5 +12 7 12 7 +12 1 12 1 +1 16 1 16 +12 3 12 3 +3 20 3 20 +20 3 20 3 +8 19 8 19 +20 1 20 1 +20 7 20 7 +20 5 20 5 +17 16 17 16 +18 19 18 19 +20 9 20 9 +17 14 17 14 +16 11 16 11 +16 13 16 13 +16 15 16 15 +16 17 16 17 +16 19 16 19 +3 18 3 18 +17 20 17 20 +3 12 3 12 +3 10 3 10 +3 16 3 16 +3 14 3 14 +10 20 +3 3 10 20 +100 +4 7 4 7 +4 4 4 4 +4 3 4 3 +4 8 4 8 +5 10 5 10 +5 11 5 11 +5 12 5 12 +5 13 5 13 +5 14 5 14 +5 15 5 15 +5 17 5 17 +5 18 5 18 +5 19 5 19 +6 20 6 20 +8 18 8 18 +5 6 5 6 +8 16 8 16 +5 4 5 4 +10 19 10 19 +10 18 10 18 +10 13 10 13 +10 12 10 12 +10 11 10 11 +10 10 10 10 +10 17 10 17 +9 20 9 20 +10 15 10 15 +8 12 8 12 +9 3 9 3 +9 7 9 7 +9 4 9 4 +9 8 9 8 +9 9 9 9 +10 9 10 9 +10 8 10 8 +10 6 10 6 +10 5 10 5 +10 3 10 3 +7 4 7 4 +7 6 7 6 +7 7 7 7 +6 11 6 11 +6 13 6 13 +6 15 6 15 +6 14 6 14 +6 18 6 18 +5 8 5 8 +5 9 5 9 +8 17 8 17 +5 7 5 7 +8 15 8 15 +8 14 8 14 +8 13 8 13 +5 3 5 3 +8 11 8 11 +8 10 8 10 +3 8 3 8 +3 9 3 9 +3 4 3 4 +3 6 3 6 +3 7 3 7 +7 18 7 18 +7 20 7 20 +9 19 9 19 +4 18 4 18 +4 13 4 13 +4 12 4 12 +4 11 4 11 +4 10 4 10 +4 16 4 16 +4 15 4 15 +4 14 4 14 +9 15 9 15 +9 16 9 16 +9 17 9 17 +9 10 9 10 +9 11 9 11 +9 12 9 12 +9 13 9 13 +7 17 7 17 +7 14 7 14 +7 12 7 12 +7 13 7 13 +7 10 7 10 +7 11 7 11 +4 20 4 20 +8 6 8 6 +8 4 8 4 +6 5 6 5 +6 7 6 7 +6 6 6 6 +6 3 6 3 +6 9 6 9 +10 16 10 16 +5 5 5 5 +3 18 3 18 +3 19 3 19 +3 12 3 12 +3 14 3 14 +3 15 3 15 +20 20 +3 3 20 20 +100 +5 12 5 12 +11 18 11 18 +11 19 11 19 +5 16 5 16 +11 14 11 14 +5 19 5 19 +11 16 11 16 +13 6 13 6 +13 7 13 7 +13 8 13 8 +15 8 15 8 +10 18 10 18 +10 11 10 11 +10 10 10 10 +10 16 10 16 +5 15 5 15 +14 8 14 8 +17 6 17 6 +14 3 14 3 +14 5 14 5 +9 3 9 3 +9 6 9 6 +9 7 9 7 +9 8 9 8 +14 14 14 14 +10 9 10 9 +16 20 16 20 +10 3 10 3 +14 10 14 10 +11 4 11 4 +6 13 6 13 +6 14 6 14 +6 17 6 17 +15 10 15 10 +15 13 15 13 +15 15 15 15 +13 10 13 10 +15 17 15 17 +15 18 15 18 +13 18 13 18 +13 19 13 19 +18 10 18 10 +18 16 18 16 +5 8 5 8 +18 19 18 19 +8 12 8 12 +8 10 8 10 +14 15 14 15 +14 13 14 13 +14 12 14 12 +3 6 3 6 +3 7 3 7 +20 10 20 10 +20 11 20 11 +20 12 20 12 +20 13 20 13 +20 14 20 14 +11 3 11 3 +11 9 11 9 +19 16 19 16 +19 17 19 17 +12 16 12 16 +13 16 13 16 +17 18 17 18 +7 20 7 20 +17 12 17 12 +17 13 17 13 +17 10 17 10 +17 11 17 11 +17 17 17 17 +17 14 17 14 +17 15 17 15 +4 10 4 10 +4 17 4 17 +9 16 9 16 +9 12 9 12 +7 19 7 19 +7 16 7 16 +7 15 7 15 +9 18 9 18 +7 13 7 13 +18 7 18 7 +18 6 18 6 +16 3 16 3 +18 8 18 8 +8 6 8 6 +6 7 6 7 +6 6 6 6 +12 9 12 9 +6 3 6 3 +12 5 12 5 +12 3 12 3 +3 20 3 20 +20 3 20 3 +12 20 12 20 +20 5 20 5 +20 9 20 9 +16 13 16 13 +16 18 16 18 +3 19 3 19 +20 20 +3 3 20 20 +130 +4 7 4 7 +4 5 4 5 +4 4 4 4 +4 3 4 3 +19 20 19 20 +4 9 4 9 +5 11 5 11 +5 12 5 12 +5 14 5 14 +11 19 11 19 +5 17 5 17 +17 8 17 8 +5 19 5 19 +11 17 11 17 +11 10 11 10 +8 19 8 19 +18 14 18 14 +13 4 13 4 +13 3 13 3 +13 8 13 8 +13 9 13 9 +10 19 10 19 +10 18 10 18 +10 11 10 11 +10 16 10 16 +10 15 10 15 +10 14 10 14 +14 8 14 8 +14 7 14 7 +12 16 12 16 +10 5 10 5 +12 10 12 10 +7 8 7 8 +12 13 12 13 +7 5 7 5 +12 12 12 12 +14 20 14 20 +11 5 11 5 +6 16 6 16 +9 19 9 19 +6 18 6 18 +11 3 11 3 +15 10 15 10 +15 11 15 11 +15 12 15 12 +15 13 15 13 +13 12 13 12 +13 13 13 13 +15 16 15 16 +15 18 15 18 +13 18 13 18 +13 19 13 19 +6 12 6 12 +15 3 15 3 +18 11 18 11 +18 17 18 17 +18 16 18 16 +18 15 18 15 +5 9 5 9 +8 16 8 16 +18 19 18 19 +18 18 18 18 +8 12 8 12 +8 10 8 10 +3 9 3 9 +12 19 12 19 +14 16 14 16 +3 4 3 4 +14 12 14 12 +14 11 14 11 +14 10 14 10 +20 12 20 12 +13 20 13 20 +20 14 20 14 +20 15 20 15 +20 16 20 16 +20 17 20 17 +11 9 11 9 +19 14 19 14 +19 15 19 15 +19 17 19 17 +19 10 19 10 +19 19 19 19 +17 18 17 18 +7 20 7 20 +17 11 17 11 +17 15 17 15 +11 20 11 20 +3 6 3 6 +19 6 19 6 +19 5 19 5 +19 3 19 3 +4 19 4 19 +18 4 18 4 +17 4 17 4 +3 7 3 7 +9 16 9 16 +9 10 9 10 +7 18 7 18 +9 13 9 13 +7 12 7 12 +7 13 7 13 +16 9 16 9 +16 8 16 8 +17 19 17 19 +18 3 18 3 +16 5 16 5 +18 9 18 9 +8 9 8 9 +8 8 8 8 +4 20 4 20 +5 8 5 8 +6 5 6 5 +15 4 15 4 +12 4 12 4 +12 7 12 7 +12 6 12 6 +6 8 6 8 +12 20 12 20 +20 7 20 7 +20 4 20 4 +20 8 20 8 +9 20 9 20 +15 5 15 5 +16 11 16 11 +16 12 16 12 +16 17 16 17 +17 20 17 20 +3 12 3 12 +3 17 3 17 +50 50 +1 1 50 50 +10 +23 38 23 38 +8 21 8 21 +21 7 21 7 +30 49 30 49 +14 35 14 35 +43 12 43 12 +14 36 14 36 +10 29 10 29 +27 31 27 31 +14 11 14 11 +50 50 +1 1 50 50 +100 +17 45 22 50 +9 33 11 36 +48 18 50 20 +40 24 42 26 +27 20 32 24 +10 29 15 32 +19 24 21 29 +27 29 32 34 +5 12 7 15 +2 7 6 11 +17 7 22 11 +19 29 22 31 +28 13 33 18 +41 23 46 27 +14 50 17 50 +39 46 44 50 +17 31 22 33 +8 43 12 47 +35 50 38 50 +2 36 7 40 +22 47 26 50 +10 23 14 27 +44 11 46 16 +6 31 8 35 +16 31 19 35 +34 45 38 48 +20 22 25 24 +25 18 27 23 +18 31 21 34 +33 28 36 32 +18 33 23 37 +14 3 17 7 +5 17 8 21 +35 8 38 10 +14 34 17 37 +44 21 46 26 +35 3 38 5 +16 25 20 30 +41 45 46 49 +41 41 45 44 +28 3 30 6 +2 16 5 19 +21 31 24 33 +45 32 47 35 +14 27 16 32 +6 16 10 18 +6 19 9 24 +5 27 9 31 +28 43 31 45 +9 36 13 38 +26 2 31 4 +26 3 30 6 +1 48 5 50 +26 9 28 13 +8 13 10 15 +46 33 49 36 +45 22 49 27 +45 23 48 28 +35 12 37 16 +26 17 29 21 +36 49 38 50 +1 2 3 5 +1 3 4 8 +49 33 50 37 +26 18 31 21 +19 15 21 20 +16 44 19 49 +34 14 39 18 +11 22 13 27 +28 29 32 31 +13 39 15 43 +35 27 37 32 +43 43 47 48 +32 13 35 18 +24 25 26 29 +24 21 27 23 +18 8 20 10 +36 29 41 32 +34 32 37 36 +46 8 49 12 +20 42 24 47 +13 41 17 46 +35 32 40 37 +35 33 38 36 +6 7 8 12 +3 24 5 28 +3 22 6 24 +12 29 14 34 +37 35 41 40 +50 39 50 41 +41 33 45 35 +4 37 7 40 +40 31 45 35 +39 37 41 41 +39 30 43 32 +43 31 46 36 +2 45 7 50 +20 47 22 50 +10 44 13 49 +3 17 5 19 +50 100 +1 1 49 81 +40 +9 33 9 33 +14 9 14 9 +50 84 50 84 +8 11 8 11 +22 59 22 59 +2 7 2 7 +20 100 20 100 +28 58 28 58 +14 97 14 97 +32 85 32 85 +32 82 32 82 +47 56 47 56 +17 37 17 37 +21 100 21 100 +31 8 31 8 +23 51 23 51 +41 1 41 1 +46 29 46 29 +42 100 42 100 +30 86 30 86 +46 48 46 48 +40 85 40 85 +14 22 14 22 +30 49 30 49 +1 91 1 91 +14 49 14 49 +16 15 16 15 +6 58 6 58 +14 87 14 87 +28 64 28 64 +43 61 43 61 +40 78 40 78 +3 51 3 51 +37 31 37 31 +11 90 11 90 +15 73 15 73 +40 58 40 58 +9 94 9 94 +16 51 16 51 +33 40 33 40 +50 100 +2 1 49 81 +400 +17 41 17 41 +34 4 34 4 +36 81 36 81 +24 84 24 84 +2 7 2 7 +2 6 2 6 +29 75 29 75 +29 70 29 70 +21 69 21 69 +6 21 6 21 +43 2 43 2 +47 98 47 98 +43 7 43 7 +35 58 35 58 +35 57 35 57 +47 94 47 94 +27 59 27 59 +30 87 30 87 +10 92 10 92 +50 12 50 12 +10 94 10 94 +24 15 24 15 +3 73 3 73 +44 92 44 92 +37 99 37 99 +44 98 44 98 +1 24 1 24 +1 22 1 22 +46 78 46 78 +15 35 15 35 +22 55 22 55 +31 31 31 31 +48 44 48 44 +31 39 31 39 +30 32 30 32 +30 30 30 30 +13 84 13 84 +13 86 13 86 +30 19 30 19 +44 8 44 8 +44 9 44 9 +40 63 40 63 +44 6 44 6 +40 67 40 67 +38 42 38 42 +6 91 6 91 +12 65 12 65 +22 7 22 7 +22 8 22 8 +42 68 42 68 +28 43 28 43 +28 42 28 42 +28 46 28 46 +4 74 4 74 +26 88 26 88 +29 100 29 100 +44 43 44 43 +45 24 45 24 +11 7 11 7 +29 37 29 37 +34 19 34 19 +19 14 19 14 +34 18 34 18 +19 10 19 10 +23 54 23 54 +23 56 23 56 +34 15 34 15 +50 100 50 100 +21 8 21 8 +24 54 24 54 +34 53 34 53 +1 13 1 13 +30 5 30 5 +47 43 47 43 +47 47 47 47 +6 66 6 66 +9 16 9 16 +3 97 3 97 +3 95 3 95 +16 93 16 93 +30 79 30 79 +22 15 22 15 +16 9 16 9 +22 81 22 81 +22 82 22 82 +16 61 16 61 +40 29 40 29 +22 88 22 88 +8 1 8 1 +36 21 36 21 +8 5 8 5 +15 43 15 43 +9 62 9 62 +15 48 15 48 +29 88 29 88 +29 81 29 81 +18 66 18 66 +47 1 47 1 +42 26 42 26 +16 62 16 62 +13 56 13 56 +14 100 14 100 +17 98 17 98 +12 50 12 50 +23 88 23 88 +19 24 19 24 +23 86 23 86 +23 84 23 84 +43 14 43 14 +11 18 11 18 +38 33 38 33 +32 31 32 31 +38 31 38 31 +7 70 7 70 +38 36 38 36 +31 97 31 97 +31 90 31 90 +23 19 23 19 +33 77 33 77 +4 43 4 43 +4 48 4 48 +19 55 19 55 +19 56 19 56 +20 53 20 53 +10 19 10 19 +47 70 47 70 +26 66 26 66 +45 11 45 11 +34 46 34 46 +34 41 34 41 +35 67 35 67 +9 59 9 59 +27 47 27 47 +9 50 9 50 +9 57 9 57 +5 39 5 39 +35 1 35 1 +35 5 35 5 +35 7 35 7 +37 62 37 62 +1 54 1 54 +1 56 1 56 +40 88 40 88 +22 65 22 65 +40 82 40 82 +2 11 2 11 +40 84 40 84 +40 86 40 86 +14 20 14 20 +14 94 14 94 +30 28 30 28 +1 34 1 34 +30 25 30 25 +40 71 40 71 +50 73 50 73 +48 35 48 35 +16 50 16 50 +16 52 16 52 +7 34 7 34 +38 75 38 75 +18 18 18 18 +32 39 32 39 +6 69 6 69 +14 97 14 97 +13 21 13 21 +13 20 13 20 +42 79 42 79 +32 44 32 44 +44 52 44 52 +8 23 8 23 +11 25 11 25 +11 29 11 29 +45 54 45 54 +21 11 21 11 +43 45 43 45 +43 46 43 46 +29 27 29 27 +19 60 19 60 +20 66 20 66 +47 22 47 22 +47 23 47 23 +6 100 6 100 +37 22 37 22 +21 86 21 86 +26 36 26 36 +46 1 46 1 +12 7 12 7 +10 54 10 54 +12 3 12 3 +36 100 36 100 +30 67 30 67 +16 84 16 84 +3 82 3 82 +27 32 27 32 +36 19 36 19 +16 14 16 14 +50 33 50 33 +46 10 46 10 +3 12 3 12 +3 16 3 16 +2 20 2 20 +25 38 25 38 +32 71 32 71 +2 28 2 28 +17 2 17 2 +13 64 13 64 +30 13 30 13 +31 12 31 12 +31 10 31 10 +27 22 27 22 +2 51 2 51 +2 53 2 53 +25 40 25 40 +30 45 30 45 +25 45 25 45 +49 90 49 90 +19 35 19 35 +49 95 49 95 +19 33 19 33 +28 64 28 64 +38 38 38 38 +20 22 20 22 +18 58 18 58 +50 86 50 86 +44 21 44 21 +11 16 11 16 +29 50 29 50 +29 57 29 57 +29 56 29 56 +29 58 29 58 +41 1 41 1 +27 77 27 77 +46 24 46 24 +9 45 9 45 +8 84 8 84 +44 86 44 86 +24 74 24 74 +3 56 3 56 +50 2 50 2 +50 4 50 4 +46 53 46 53 +46 54 46 54 +46 55 46 55 +40 99 40 99 +31 57 31 57 +2 62 2 62 +40 91 40 91 +4 80 4 80 +14 18 14 18 +20 91 20 91 +20 92 20 92 +50 65 50 65 +5 54 5 54 +36 46 36 46 +5 50 5 50 +5 52 5 52 +15 64 15 64 +16 49 16 49 +16 43 16 43 +38 3 38 3 +7 21 7 21 +32 25 32 25 +7 27 7 27 +38 67 38 67 +28 26 28 26 +28 28 28 28 +39 12 39 12 +49 20 49 20 +13 31 13 31 +39 18 39 18 +42 44 42 44 +4 15 4 15 +44 66 44 66 +42 8 42 8 +29 15 29 15 +7 95 7 95 +38 18 38 18 +11 30 11 30 +38 15 38 15 +7 98 7 98 +38 12 38 12 +34 35 34 35 +17 97 17 97 +35 30 35 30 +43 33 43 33 +20 70 20 70 +23 73 23 73 +23 70 23 70 +49 51 49 51 +1 32 1 32 +10 36 10 36 +10 33 10 33 +37 32 37 32 +26 48 26 48 +24 2 24 2 +24 3 24 3 +38 88 38 88 +6 52 6 52 +9 37 9 37 +4 1 4 1 +5 12 5 12 +5 14 5 14 +22 79 22 79 +45 5 45 5 +41 22 41 22 +48 82 48 82 +48 84 48 84 +50 27 50 27 +13 4 13 4 +9 86 9 86 +15 23 15 23 +22 47 22 47 +32 67 32 67 +13 74 13 74 +13 75 13 75 +31 23 31 23 +31 26 31 26 +32 7 32 7 +39 51 39 51 +39 56 39 56 +5 82 5 82 +33 20 33 20 +25 93 25 93 +7 58 7 58 +25 96 25 96 +11 77 11 77 +49 12 49 12 +42 96 42 96 +23 37 23 37 +23 36 23 36 +20 5 20 5 +4 62 4 62 +4 66 4 66 +18 46 18 46 +33 51 33 51 +7 7 7 7 +27 68 27 68 +35 93 35 93 +8 54 8 54 +6 11 6 11 +6 14 6 14 +45 35 45 35 +21 36 21 36 +19 90 19 90 +29 49 29 49 +15 2 15 2 +27 66 27 66 +8 99 8 99 +8 98 8 98 +26 17 26 17 +12 97 12 97 +26 13 26 13 +3 44 3 44 +3 47 3 47 +3 46 3 46 +1 76 1 76 +1 77 1 77 +1 71 1 71 +48 61 48 61 +48 60 48 60 +48 65 48 65 +31 68 31 68 +31 64 31 64 +31 62 31 62 +30 48 30 48 +46 80 46 80 +46 85 46 85 +17 36 17 36 +30 47 30 47 +40 7 40 7 +36 30 36 30 +36 35 36 35 +5 41 5 41 +41 19 41 19 +16 79 16 79 +3 37 3 37 +16 75 16 75 +18 79 18 79 +32 14 32 14 +29 97 29 97 +18 70 18 70 +28 31 28 31 +8 46 8 46 +1 19 1 19 +18 85 18 85 +13 43 13 43 +27 89 27 89 +45 75 45 75 +12 22 12 22 +44 72 44 72 +31 87 31 87 +20 48 20 48 +49 17 49 17 +23 62 23 62 +23 69 23 69 +28 89 28 89 +20 43 20 43 +42 98 42 98 +20 45 20 45 +49 45 49 45 +50 100 +2 3 49 99 +450 +36 88 36 88 +34 4 34 4 +17 49 17 49 +26 52 26 52 +21 63 21 63 +8 40 8 40 +17 31 17 31 +17 34 17 34 +47 91 47 91 +47 95 47 95 +9 28 9 28 +10 22 10 22 +9 27 9 27 +43 92 43 92 +10 91 10 91 +24 19 24 19 +48 92 48 92 +46 72 46 72 +46 70 46 70 +15 32 15 32 +27 4 27 4 +46 78 46 78 +1 29 1 29 +22 56 22 56 +31 36 31 36 +31 30 31 30 +22 53 22 53 +25 17 25 17 +46 58 46 58 +22 59 22 59 +14 30 14 30 +14 36 14 36 +42 12 42 12 +42 44 42 44 +42 17 42 17 +44 8 44 8 +44 5 44 5 +44 6 44 6 +44 7 44 7 +41 48 41 48 +11 41 11 41 +28 2 28 2 +12 63 12 63 +6 95 6 95 +12 65 12 65 +6 97 6 97 +25 85 25 85 +28 48 28 48 +39 71 39 71 +42 61 42 61 +4 79 4 79 +4 70 4 70 +3 92 3 92 +8 14 8 14 +8 11 8 11 +12 11 12 11 +9 11 9 11 +11 6 11 6 +11 4 11 4 +11 5 11 5 +35 14 35 14 +23 55 23 55 +47 5 47 5 +1 15 1 15 +1 13 1 13 +41 94 41 94 +2 58 2 58 +37 59 37 59 +30 3 30 3 +6 70 6 70 +26 28 26 28 +30 8 30 8 +6 79 6 79 +47 40 47 40 +10 60 10 60 +30 77 30 77 +3 93 3 93 +3 97 3 97 +30 70 30 70 +16 91 16 91 +31 71 31 71 +48 76 48 76 +16 92 16 92 +22 16 22 16 +31 76 31 76 +39 22 39 22 +1 88 1 88 +22 82 22 82 +22 84 22 84 +22 87 22 87 +40 26 40 26 +16 69 16 69 +15 48 15 48 +30 84 30 84 +29 88 29 88 +11 80 11 80 +11 87 11 87 +18 65 18 65 +42 23 42 23 +42 25 42 25 +42 26 42 26 +30 81 30 81 +12 42 12 42 +4 38 4 38 +39 31 39 31 +14 60 14 60 +39 33 39 33 +32 95 32 95 +45 67 45 67 +43 15 43 15 +43 14 43 14 +11 18 11 18 +38 30 38 30 +43 18 43 18 +31 96 31 96 +23 10 23 10 +28 92 28 92 +46 100 46 100 +31 91 31 91 +4 46 4 46 +4 43 4 43 +33 79 33 79 +20 50 20 50 +50 92 50 92 +50 90 50 90 +26 65 26 65 +45 10 45 10 +44 18 44 18 +44 17 44 17 +44 15 44 15 +26 69 26 69 +37 17 37 17 +35 62 35 62 +35 67 35 67 +35 65 35 65 +9 58 9 58 +16 26 16 26 +1 55 1 55 +1 58 1 58 +42 34 42 34 +46 43 46 43 +22 63 22 63 +48 47 48 47 +40 82 40 82 +14 23 14 23 +30 28 30 28 +14 27 14 27 +13 91 13 91 +50 76 50 76 +40 70 40 70 +40 71 40 71 +15 36 15 36 +50 78 50 78 +26 2 26 2 +48 37 48 37 +16 55 16 55 +16 57 16 57 +37 41 37 41 +32 37 32 37 +32 30 32 30 +32 39 32 39 +3 9 3 9 +34 92 34 92 +34 95 34 95 +13 23 13 23 +20 11 20 11 +20 19 20 19 +49 33 49 33 +17 18 17 18 +44 54 44 54 +8 23 8 23 +47 50 47 50 +8 24 8 24 +8 25 8 25 +21 16 21 16 +21 12 21 12 +43 48 43 48 +43 45 43 45 +29 20 29 20 +43 43 43 43 +19 63 19 63 +19 62 19 62 +19 65 19 65 +36 5 36 5 +36 4 36 4 +21 40 21 40 +20 69 20 69 +41 87 41 87 +41 85 41 85 +13 55 13 55 +7 35 7 35 +6 41 6 41 +26 38 26 38 +21 86 21 86 +46 4 46 4 +6 7 6 7 +12 4 12 4 +10 53 10 53 +12 3 12 3 +20 2 20 2 +20 5 20 5 +3 85 3 85 +16 86 16 86 +3 82 3 82 +24 36 24 36 +36 14 36 14 +5 63 5 63 +5 62 5 62 +27 32 27 32 +5 68 5 68 +40 30 40 30 +40 35 40 35 +46 10 46 10 +15 53 15 53 +25 39 25 39 +43 94 43 94 +2 29 2 29 +32 77 32 77 +30 14 30 14 +17 2 17 2 +30 16 30 16 +42 37 42 37 +13 61 13 61 +30 12 30 12 +31 13 31 13 +30 98 30 98 +32 86 32 86 +32 88 32 88 +39 47 39 47 +39 46 39 46 +2 59 2 59 +41 42 41 42 +40 47 40 47 +39 91 39 91 +40 42 40 42 +38 22 38 22 +45 94 45 94 +49 93 49 93 +12 49 12 49 +49 94 49 94 +27 29 27 29 +7 68 7 68 +11 65 11 65 +49 67 49 67 +49 62 49 62 +28 66 28 66 +11 95 11 95 +18 55 18 55 +18 52 18 52 +11 93 11 93 +27 5 27 5 +43 13 43 13 +33 43 33 43 +20 27 20 27 +47 68 47 68 +50 58 50 58 +50 80 50 80 +50 81 50 81 +50 84 50 84 +14 6 14 6 +9 2 9 2 +19 87 19 87 +9 5 9 5 +15 86 15 86 +44 21 44 21 +29 51 29 51 +35 77 35 77 +29 57 29 57 +34 79 34 79 +7 73 7 73 +8 60 8 60 +9 49 9 49 +41 6 41 6 +41 9 41 9 +33 32 33 32 +9 40 9 40 +27 73 27 73 +27 72 27 72 +24 79 24 79 +5 26 5 26 +37 81 37 81 +37 71 37 71 +50 3 50 3 +1 45 1 45 +1 49 1 49 +2 60 2 60 +22 76 22 76 +2 65 2 65 +22 72 22 72 +40 95 40 95 +4 81 4 81 +4 84 4 84 +14 16 14 16 +39 87 39 87 +20 95 20 95 +20 96 20 96 +32 8 32 8 +50 64 50 64 +1 2 1 2 +36 42 36 42 +1 5 1 5 +15 63 15 63 +32 18 32 18 +32 21 32 21 +32 28 32 28 +28 21 28 21 +34 83 34 83 +34 80 34 80 +34 84 34 84 +28 28 28 28 +14 84 14 84 +39 13 39 13 +42 41 42 41 +13 37 13 37 +49 27 49 27 +18 92 18 92 +38 18 38 18 +29 19 29 19 +35 38 35 38 +17 93 17 93 +34 34 34 34 +35 32 35 32 +43 37 43 37 +19 72 19 72 +19 77 19 77 +49 57 49 57 +49 53 49 53 +4 27 4 27 +1 32 1 32 +1 30 1 30 +36 94 36 94 +42 7 42 7 +21 79 21 79 +38 81 38 81 +26 40 26 40 +17 23 17 23 +17 29 17 29 +17 60 17 60 +27 21 27 21 +30 96 30 96 +30 90 30 90 +5 10 5 10 +41 20 41 20 +37 86 37 86 +45 3 45 3 +50 24 50 24 +9 89 9 89 +13 3 13 3 +9 82 9 82 +15 27 15 27 +32 69 32 69 +22 40 22 40 +2 31 2 31 +25 22 25 22 +25 21 25 21 +13 70 13 70 +13 73 13 73 +14 40 14 40 +31 22 31 22 +2 67 2 67 +31 24 31 24 +36 74 36 74 +39 52 39 52 +39 55 39 55 +41 53 41 53 +5 82 5 82 +5 81 5 81 +41 59 41 59 +41 58 41 58 +33 28 33 28 +45 88 45 88 +38 58 38 58 +33 23 33 23 +49 85 49 85 +20 91 20 91 +42 95 42 95 +49 16 49 16 +23 36 23 36 +18 42 18 42 +4 65 4 65 +14 10 14 10 +7 3 7 3 +26 89 26 89 +19 95 19 95 +26 80 26 80 +43 67 43 67 +43 65 43 65 +43 63 43 63 +8 73 8 73 +8 72 8 72 +8 77 8 77 +15 7 15 7 +15 4 15 4 +8 92 8 92 +12 95 12 95 +3 48 3 48 +12 97 12 97 +26 10 26 10 +3 43 3 43 +6 69 6 69 +37 45 37 45 +26 19 26 19 +10 71 10 71 +10 77 10 77 +1 79 1 79 +10 78 10 78 +31 69 31 69 +2 71 2 71 +1 94 1 94 +27 18 27 18 +39 98 39 98 +12 70 12 70 +39 92 39 92 +40 7 40 7 +50 50 50 50 +5 49 5 49 +5 44 5 44 +9 76 9 76 +9 70 9 70 +41 11 41 11 +41 13 41 13 +3 32 3 32 +3 33 3 33 +29 98 29 98 +36 32 36 32 +28 30 28 30 +42 50 42 50 +18 85 18 85 +4 24 4 24 +39 29 39 29 +18 88 18 88 +33 62 33 62 +44 79 44 79 +45 74 45 74 +45 71 45 71 +45 79 45 79 +49 8 49 8 +49 4 49 4 +49 6 49 6 +34 23 34 23 +23 60 23 60 +31 83 31 83 +34 29 34 29 +23 69 23 69 +43 24 43 24 +20 43 20 43 +20 40 20 40 +19 45 19 45 +49 45 49 45 +37 51 37 51 +50 100 +2 3 49 99 +100 +48 18 50 49 +7 78 46 94 +28 13 42 50 +43 19 50 32 +11 62 22 80 +48 85 50 95 +41 25 50 60 +22 23 33 47 +25 40 50 72 +15 22 34 36 +22 28 45 49 +45 97 45 97 +25 22 49 62 +42 5 50 22 +31 23 50 48 +10 98 44 100 +37 94 37 94 +37 95 37 95 +47 83 47 83 +43 15 50 54 +8 55 24 91 +1 22 30 37 +40 54 50 66 +34 100 50 100 +38 58 50 71 +47 60 50 87 +33 21 49 55 +50 85 50 100 +50 87 50 100 +26 70 47 100 +9 8 24 21 +15 84 15 84 +24 67 50 95 +47 89 47 89 +17 70 28 100 +46 23 50 45 +20 85 41 100 +5 24 31 52 +50 77 50 100 +40 77 40 77 +40 72 50 85 +29 44 49 60 +28 42 47 72 +29 40 50 55 +28 44 50 73 +26 2 41 29 +26 9 37 39 +48 56 50 84 +8 15 47 46 +8 94 35 100 +3 3 20 27 +28 58 39 83 +49 100 50 100 +1 77 34 100 +16 43 43 57 +41 62 50 87 +47 37 50 48 +8 21 40 57 +8 26 34 41 +27 19 50 34 +21 97 41 100 +19 9 45 39 +49 20 50 35 +35 26 50 42 +19 5 44 44 +5 41 35 77 +10 62 22 72 +18 96 44 100 +14 89 34 100 +3 92 15 100 +32 11 50 39 +32 10 43 21 +29 93 29 93 +11 34 40 53 +42 50 50 89 +28 88 28 88 +24 29 45 48 +18 84 31 100 +4 22 34 54 +21 85 44 100 +35 32 50 49 +36 26 50 65 +46 3 50 19 +50 42 50 78 +45 75 45 75 +1 17 33 33 +47 16 50 28 +47 3 50 43 +49 5 50 34 +24 38 40 57 +17 97 17 97 +22 97 22 97 +16 19 38 55 +13 53 45 69 +6 52 44 62 +17 26 35 51 +19 45 50 65 +25 50 38 82 +32 97 32 97 +10 47 41 69 +50 100 +3 1 49 99 +0 +50 100 +1 1 47 93 +200 +45 60 45 60 +4 5 4 5 +23 89 23 89 +30 99 30 99 +4 100 4 100 +25 34 25 34 +19 21 19 21 +4 9 4 9 +19 22 19 22 +28 19 28 19 +43 14 43 14 +42 36 42 36 +17 9 17 9 +38 30 38 30 +7 70 7 70 +7 71 7 71 +10 37 10 37 +45 4 45 4 +28 93 28 93 +45 2 45 2 +50 21 50 21 +39 45 39 45 +8 40 8 40 +23 82 23 82 +34 38 34 38 +34 8 34 8 +15 47 15 47 +33 79 33 79 +20 50 20 50 +5 96 5 96 +49 28 49 28 +32 68 32 68 +45 98 45 98 +50 99 50 99 +22 26 22 26 +42 2 42 2 +47 70 47 70 +17 82 17 82 +24 18 24 18 +23 84 23 84 +48 6 48 6 +11 61 11 61 +10 99 10 99 +10 21 10 21 +23 5 23 5 +36 75 36 75 +13 66 13 66 +28 65 28 65 +39 53 39 53 +13 64 13 64 +4 52 4 52 +8 59 8 59 +40 64 40 64 +42 40 42 40 +17 67 17 67 +33 24 33 24 +45 84 45 84 +36 39 36 39 +47 52 47 52 +25 93 25 93 +9 3 9 3 +19 81 19 81 +19 80 19 80 +26 79 26 79 +44 21 44 21 +5 31 5 31 +26 33 26 33 +42 97 42 97 +42 98 42 98 +23 35 23 35 +29 2 29 2 +24 90 24 90 +4 67 4 67 +44 7 44 7 +22 69 22 69 +8 60 8 60 +48 28 48 28 +48 45 48 45 +41 3 41 3 +22 67 22 67 +18 23 18 23 +33 38 33 38 +46 25 46 25 +35 90 35 90 +46 26 46 26 +6 94 6 94 +33 31 33 31 +13 20 13 20 +45 35 45 35 +21 36 21 36 +14 29 14 29 +26 83 26 83 +26 82 26 82 +15 11 15 11 +15 13 15 13 +40 71 40 71 +37 79 37 79 +29 44 29 44 +26 41 26 41 +32 57 32 57 +34 69 34 69 +8 71 8 71 +37 10 37 10 +1 48 1 48 +8 75 8 75 +8 77 8 77 +11 51 11 51 +14 50 14 50 +6 17 6 17 +22 74 22 74 +11 59 11 59 +38 72 38 72 +8 11 8 11 +34 91 34 91 +32 3 32 3 +8 92 8 92 +43 52 43 52 +12 97 12 97 +20 13 20 13 +49 39 49 39 +26 11 26 11 +1 4 1 4 +19 15 19 15 +30 22 30 22 +37 7 37 7 +15 68 15 68 +41 62 41 62 +47 58 47 58 +47 31 47 31 +44 55 44 55 +31 65 31 65 +32 28 32 28 +32 29 32 29 +34 83 34 83 +28 22 28 22 +34 84 34 84 +41 99 41 99 +30 47 30 47 +17 81 17 81 +30 7 30 7 +42 48 42 48 +17 84 17 84 +50 55 50 55 +42 43 42 43 +42 42 42 42 +25 5 25 5 +22 95 22 95 +30 31 30 31 +39 18 39 18 +19 60 19 60 +1 67 1 67 +46 99 46 99 +42 52 42 52 +44 65 44 65 +31 75 31 75 +42 51 42 51 +7 90 7 90 +7 91 7 91 +45 47 45 47 +29 19 29 19 +43 39 43 39 +34 36 34 36 +5 78 5 78 +6 46 6 46 +26 39 26 39 +13 46 13 46 +9 61 9 61 +33 16 33 16 +6 6 6 6 +33 10 33 10 +12 8 12 8 +38 85 38 85 +9 99 9 99 +16 88 16 88 +3 89 3 89 +17 93 17 93 +16 82 16 82 +29 82 29 82 +1 31 1 31 +22 83 22 83 +40 65 40 65 +7 83 7 83 +8 100 8 100 +35 56 35 56 +49 1 49 1 +49 2 49 2 +47 9 47 9 +22 84 22 84 +40 39 40 39 +31 86 31 86 +28 81 28 81 +41 90 41 90 +50 31 50 31 +43 23 43 23 +23 37 23 37 +2 43 2 43 +40 45 40 45 +35 44 35 44 +8 38 8 38 +49 40 49 40 +50 100 +45 47 3 93 +200 +2 25 2 25 +17 47 17 47 +2 27 2 27 +32 70 32 70 +32 76 32 76 +13 63 13 63 +17 5 17 5 +31 17 31 17 +31 94 31 94 +31 95 31 95 +46 100 46 100 +11 95 11 95 +39 46 39 46 +46 60 46 60 +22 24 22 24 +22 45 22 45 +35 57 35 57 +19 52 19 52 +15 22 15 22 +40 41 40 41 +41 43 41 43 +43 88 43 88 +12 46 12 46 +45 98 45 98 +42 2 42 2 +45 96 45 96 +19 32 19 32 +42 85 42 85 +50 17 50 17 +45 10 45 10 +7 64 7 64 +19 86 19 86 +6 39 6 39 +29 77 29 77 +47 83 47 83 +34 47 34 47 +34 44 34 44 +22 33 22 33 +8 56 8 56 +33 48 33 48 +11 18 11 18 +15 31 15 31 +33 42 33 42 +27 43 27 43 +47 68 47 68 +38 52 38 52 +31 30 31 30 +12 79 12 79 +27 45 27 45 +3 49 3 49 +6 82 6 82 +25 16 25 16 +22 58 22 58 +19 83 19 83 +21 47 21 47 +25 97 25 97 +21 41 21 41 +11 73 11 73 +42 12 42 12 +5 35 5 35 +5 32 5 32 +7 57 7 57 +24 66 24 66 +16 29 16 29 +49 12 49 12 +35 73 35 73 +10 5 10 5 +23 32 23 32 +1 55 1 55 +33 55 33 55 +44 34 44 34 +22 62 22 62 +9 48 9 48 +47 69 47 69 +48 40 48 40 +17 75 17 75 +2 16 2 16 +7 48 7 48 +22 1 22 1 +45 30 45 30 +41 31 41 31 +19 90 19 90 +5 27 5 27 +36 50 36 50 +47 100 47 100 +43 63 43 63 +13 10 13 10 +49 8 49 8 +36 58 36 58 +40 78 40 78 +29 41 29 41 +33 1 33 1 +50 3 50 3 +46 50 46 50 +4 71 4 71 +24 45 24 45 +1 1 1 1 +24 43 24 43 +37 92 37 92 +38 79 38 79 +1 84 1 84 +5 3 5 3 +25 18 25 18 +33 86 33 86 +8 91 8 91 +14 15 14 15 +39 86 39 86 +45 20 45 20 +2 95 2 95 +6 65 6 65 +1 8 1 8 +13 26 13 26 +42 78 42 78 +36 46 36 46 +6 89 6 89 +36 43 36 43 +38 8 38 8 +19 13 19 13 +23 51 23 51 +19 19 19 19 +32 27 32 27 +1 15 1 15 +8 20 8 20 +31 87 31 87 +8 24 8 24 +45 83 45 83 +25 40 25 40 +28 22 28 22 +1 90 1 90 +4 95 4 95 +1 93 1 93 +45 53 45 53 +40 47 40 47 +16 14 16 14 +39 67 39 67 +43 48 43 48 +40 17 40 17 +27 92 27 92 +17 89 17 89 +25 4 25 4 +19 3 19 3 +39 18 39 18 +7 59 7 59 +3 38 3 38 +23 48 23 48 +3 36 3 36 +23 43 23 43 +4 15 4 15 +13 88 13 88 +30 73 30 73 +32 15 32 15 +7 15 7 15 +18 6 18 6 +37 22 37 22 +24 20 24 20 +7 53 7 53 +38 17 38 17 +6 52 6 52 +38 13 38 13 +11 39 11 39 +4 26 4 26 +4 27 4 27 +17 91 17 91 +22 87 22 87 +17 26 17 26 +21 88 21 88 +38 99 38 99 +13 46 13 46 +3 26 3 26 +37 49 37 49 +23 75 23 75 +46 11 46 11 +20 3 20 3 +32 61 32 61 +47 16 47 16 +49 95 49 95 +29 82 29 82 +10 36 10 36 +44 75 44 75 +36 16 36 16 +18 36 18 36 +27 33 27 33 +49 5 49 5 +41 35 41 35 +31 80 31 80 +38 80 38 80 +41 30 41 30 +10 8 10 8 +14 62 14 62 +24 9 24 9 +20 43 20 43 +20 42 20 42 +17 24 17 24 +32 95 32 95 +25 59 25 59 +20 44 20 44 +3 11 3 11 +25 52 25 52 +17 29 17 29 +15 53 15 53 +50 100 +5 97 43 3 +400 +24 80 24 80 +24 86 24 86 +6 29 6 29 +34 54 34 54 +43 7 43 7 +17 36 17 36 +43 9 43 9 +35 51 35 51 +27 52 27 52 +27 58 27 58 +9 23 9 23 +24 14 24 14 +27 93 27 93 +33 54 33 54 +27 92 27 92 +16 32 16 32 +46 71 46 71 +46 76 46 76 +46 79 46 79 +17 5 17 5 +22 55 22 55 +22 50 22 50 +25 14 25 14 +39 62 39 62 +25 70 25 70 +31 46 31 46 +40 69 40 69 +48 20 48 20 +40 67 40 67 +18 25 18 25 +18 20 18 20 +7 42 7 42 +28 2 28 2 +12 61 12 61 +12 65 12 65 +12 66 12 66 +13 16 13 16 +13 15 13 15 +28 47 28 47 +32 59 32 59 +32 58 32 58 +44 45 44 45 +15 91 15 91 +12 15 12 15 +12 11 12 11 +43 53 43 53 +29 38 29 38 +31 100 31 100 +23 57 23 57 +26 22 26 22 +47 41 47 41 +10 67 10 67 +47 48 47 48 +31 78 31 78 +22 19 22 19 +30 71 30 71 +48 74 48 74 +22 14 22 14 +46 95 46 95 +46 96 46 96 +46 92 46 92 +22 80 22 80 +8 3 8 3 +8 2 8 2 +5 76 5 76 +8 6 8 6 +40 21 40 21 +15 40 15 40 +19 32 19 32 +47 8 47 8 +39 30 39 30 +2 40 2 40 +32 97 32 97 +45 61 45 61 +45 63 45 63 +12 54 12 54 +19 27 19 27 +23 84 23 84 +38 39 38 39 +43 19 43 19 +18 15 18 15 +31 98 31 98 +20 55 20 55 +49 75 49 75 +17 54 17 54 +42 9 42 9 +47 71 47 71 +10 15 10 15 +26 61 26 61 +48 7 48 7 +37 10 37 10 +45 18 45 18 +6 38 6 38 +6 32 6 32 +8 51 8 51 +27 43 27 43 +27 47 27 47 +10 84 10 84 +5 32 5 32 +3 61 3 61 +16 21 16 21 +16 23 16 23 +34 97 34 97 +1 59 1 59 +12 95 12 95 +22 61 22 61 +48 46 48 46 +22 67 22 67 +22 64 22 64 +48 49 48 49 +14 95 14 95 +14 23 14 23 +13 97 13 97 +13 91 13 91 +50 77 50 77 +50 76 50 76 +34 55 34 55 +50 78 50 78 +41 70 41 70 +41 76 41 76 +26 2 26 2 +48 37 48 37 +16 56 16 56 +11 52 11 52 +11 53 11 53 +11 56 11 56 +32 32 32 32 +38 72 38 72 +3 8 3 8 +3 9 3 9 +28 52 28 52 +34 96 34 96 +3 4 3 4 +20 11 20 11 +20 12 20 12 +13 20 13 20 +14 92 14 92 +20 16 20 16 +49 38 49 38 +20 18 20 18 +13 29 13 29 +42 70 42 70 +32 47 32 47 +44 53 44 53 +44 55 44 55 +8 20 8 20 +8 27 8 27 +45 59 45 59 +11 20 11 20 +11 29 11 29 +17 87 17 87 +17 89 17 89 +17 88 17 88 +43 41 43 41 +20 62 20 62 +23 47 23 47 +47 26 47 26 +47 27 47 27 +47 25 47 25 +47 22 47 22 +41 86 41 86 +17 100 17 100 +18 9 18 9 +6 43 6 43 +21 87 21 87 +33 25 33 25 +20 5 20 5 +3 85 3 85 +3 87 3 87 +16 81 16 81 +24 36 24 36 +24 34 24 34 +24 35 24 35 +27 32 27 32 +27 31 27 31 +36 18 36 18 +40 38 40 38 +22 93 22 93 +40 31 40 31 +40 37 40 37 +46 16 46 16 +46 10 46 10 +31 4 31 4 +15 56 15 56 +31 7 31 7 +9 90 9 90 +15 51 15 51 +3 15 3 15 +2 24 2 24 +2 20 2 20 +32 71 32 71 +25 37 25 37 +28 18 28 18 +30 14 30 14 +42 37 42 37 +28 11 28 11 +28 12 28 12 +32 83 32 83 +25 42 25 42 +38 20 38 20 +19 35 19 35 +49 95 49 95 +49 96 49 96 +7 68 7 68 +11 66 11 66 +49 63 49 63 +33 46 33 46 +4 59 4 59 +33 40 33 40 +50 81 50 81 +35 85 35 85 +14 5 14 5 +19 83 19 83 +21 47 21 47 +29 53 29 53 +35 75 35 75 +29 58 29 58 +8 66 8 66 +41 7 41 7 +9 41 9 41 +46 20 46 20 +27 70 27 70 +24 78 24 78 +28 4 28 4 +5 21 5 21 +24 73 24 73 +5 22 5 22 +15 18 15 18 +3 54 3 54 +3 50 3 50 +1 43 1 43 +50 5 50 5 +46 50 46 50 +2 68 2 68 +22 77 22 77 +20 99 20 99 +32 4 32 4 +4 86 4 86 +50 62 50 62 +36 49 36 49 +50 60 50 60 +1 2 1 2 +36 41 36 41 +15 61 15 61 +6 45 6 45 +41 64 41 64 +38 4 38 4 +38 7 38 7 +7 24 7 24 +38 65 38 65 +28 21 28 21 +28 25 28 25 +34 85 34 85 +14 82 14 82 +39 15 39 15 +39 10 39 10 +19 9 19 9 +42 42 42 42 +19 4 19 4 +13 30 13 30 +13 31 13 31 +3 56 3 56 +4 18 4 18 +25 75 25 75 +25 76 25 76 +4 16 4 16 +44 68 44 68 +11 34 11 34 +37 70 37 70 +29 11 29 11 +38 14 38 14 +12 36 12 36 +17 94 17 94 +34 30 34 30 +17 98 17 98 +35 34 35 34 +34 38 34 38 +33 14 33 14 +20 75 20 75 +49 58 49 58 +49 50 49 50 +49 53 49 53 +49 52 49 52 +13 49 13 49 +47 18 47 18 +36 92 36 92 +47 77 47 77 +39 25 39 25 +38 92 38 92 +26 45 26 45 +26 46 26 46 +35 48 35 48 +8 32 8 32 +35 44 35 44 +35 41 35 41 +26 36 26 36 +30 99 30 99 +48 10 48 10 +30 93 30 93 +44 85 44 85 +41 21 41 21 +50 29 50 29 +41 25 41 25 +37 81 37 81 +50 22 50 22 +9 84 9 84 +43 88 43 88 +40 91 40 91 +22 41 22 41 +25 26 25 26 +43 83 43 83 +43 84 43 84 +23 9 23 9 +14 42 14 42 +13 79 13 79 +36 74 36 74 +36 76 36 76 +29 74 29 74 +5 89 5 89 +18 34 18 34 +45 86 45 86 +6 87 6 87 +6 82 6 82 +26 96 26 96 +10 8 10 8 +10 3 10 3 +41 57 41 57 +20 39 20 39 +18 44 18 44 +18 45 18 45 +4 64 4 64 +20 36 20 36 +20 37 20 37 +44 31 44 31 +21 33 21 33 +19 98 19 98 +6 14 6 14 +15 90 15 90 +21 38 21 38 +45 38 45 38 +29 48 29 48 +43 61 43 61 +33 4 33 4 +36 44 36 44 +36 14 36 14 +8 72 8 72 +8 74 8 74 +34 62 34 62 +21 76 21 76 +24 49 24 49 +1 7 1 7 +8 92 8 92 +8 90 8 90 +6 64 6 64 +26 10 26 10 +10 70 10 70 +47 53 47 53 +2 78 2 78 +48 67 48 67 +31 66 31 66 +31 65 31 65 +1 94 1 94 +4 91 4 91 +46 87 46 87 +39 97 39 97 +39 94 39 94 +30 46 30 46 +30 47 30 47 +30 44 30 44 +40 10 40 10 +50 57 50 57 +50 59 50 59 +36 35 36 35 +9 76 9 76 +16 78 16 78 +41 13 41 13 +16 70 16 70 +18 79 18 79 +18 78 18 78 +32 14 32 14 +29 97 29 97 +29 91 29 91 +28 32 28 32 +18 84 18 84 +18 86 18 86 +4 20 4 20 +13 41 13 41 +25 63 25 63 +25 65 25 65 +45 77 45 77 +12 21 12 21 +12 22 12 22 +49 2 49 2 +23 67 23 67 +28 83 28 83 +43 23 43 23 +46 19 46 19 +33 63 33 63 +20 40 20 40 +38 89 38 89 +10 10 +10 10 1 1 +2 +2 2 10 3 +1 5 9 6 +20 20 +1 1 20 20 +6 +2 2 3 20 +5 1 6 19 +8 2 9 20 +11 1 12 19 +14 2 15 20 +17 1 18 19 +1 50 +1 1 1 50 +1 +1 22 1 22 +1 50 +1 50 1 1 +10 +1 25 1 25 +1 16 1 16 +1 36 1 36 +1 22 1 22 +1 42 1 42 +1 27 1 27 +1 34 1 34 +1 44 1 44 +1 48 1 48 +1 28 1 28 +11 51 +11 3 11 51 +1 +11 36 11 36 +50 1 +1 1 50 1 +4 +46 1 46 1 +17 1 17 1 +39 1 39 1 +7 1 7 1 +50 1 +50 1 1 1 +15 +37 1 37 1 +20 1 20 1 +4 1 4 1 +11 1 11 1 +43 1 43 1 +5 1 5 1 +17 1 17 1 +9 1 9 1 +39 1 39 1 +18 1 18 1 +35 1 35 1 +49 1 49 1 +3 1 3 1 +38 1 38 1 +36 1 36 1 +57 13 +55 13 5 13 +15 +40 13 40 13 +16 13 16 13 +20 13 20 13 +26 13 26 13 +9 13 9 13 +17 13 17 13 +46 13 46 13 +8 13 8 13 +23 13 23 13 +31 13 31 13 +6 13 6 13 +4 13 4 13 +34 13 34 13 +57 13 57 13 +27 13 27 13 +500 500 +1 1 500 500 +997 +2 2 499 499 +2 1 2 1 +2 500 2 500 +4 1 4 1 +4 500 4 500 +6 1 6 1 +6 500 6 500 +8 1 8 1 +8 500 8 500 +10 1 10 1 +10 500 10 500 +12 1 12 1 +12 500 12 500 +14 1 14 1 +14 500 14 500 +16 1 16 1 +16 500 16 500 +18 1 18 1 +18 500 18 500 +20 1 20 1 +20 500 20 500 +22 1 22 1 +22 500 22 500 +24 1 24 1 +24 500 24 500 +26 1 26 1 +26 500 26 500 +28 1 28 1 +28 500 28 500 +30 1 30 1 +30 500 30 500 +32 1 32 1 +32 500 32 500 +34 1 34 1 +34 500 34 500 +36 1 36 1 +36 500 36 500 +38 1 38 1 +38 500 38 500 +40 1 40 1 +40 500 40 500 +42 1 42 1 +42 500 42 500 +44 1 44 1 +44 500 44 500 +46 1 46 1 +46 500 46 500 +48 1 48 1 +48 500 48 500 +50 1 50 1 +50 500 50 500 +52 1 52 1 +52 500 52 500 +54 1 54 1 +54 500 54 500 +56 1 56 1 +56 500 56 500 +58 1 58 1 +58 500 58 500 +60 1 60 1 +60 500 60 500 +62 1 62 1 +62 500 62 500 +64 1 64 1 +64 500 64 500 +66 1 66 1 +66 500 66 500 +68 1 68 1 +68 500 68 500 +70 1 70 1 +70 500 70 500 +72 1 72 1 +72 500 72 500 +74 1 74 1 +74 500 74 500 +76 1 76 1 +76 500 76 500 +78 1 78 1 +78 500 78 500 +80 1 80 1 +80 500 80 500 +82 1 82 1 +82 500 82 500 +84 1 84 1 +84 500 84 500 +86 1 86 1 +86 500 86 500 +88 1 88 1 +88 500 88 500 +90 1 90 1 +90 500 90 500 +92 1 92 1 +92 500 92 500 +94 1 94 1 +94 500 94 500 +96 1 96 1 +96 500 96 500 +98 1 98 1 +98 500 98 500 +100 1 100 1 +100 500 100 500 +102 1 102 1 +102 500 102 500 +104 1 104 1 +104 500 104 500 +106 1 106 1 +106 500 106 500 +108 1 108 1 +108 500 108 500 +110 1 110 1 +110 500 110 500 +112 1 112 1 +112 500 112 500 +114 1 114 1 +114 500 114 500 +116 1 116 1 +116 500 116 500 +118 1 118 1 +118 500 118 500 +120 1 120 1 +120 500 120 500 +122 1 122 1 +122 500 122 500 +124 1 124 1 +124 500 124 500 +126 1 126 1 +126 500 126 500 +128 1 128 1 +128 500 128 500 +130 1 130 1 +130 500 130 500 +132 1 132 1 +132 500 132 500 +134 1 134 1 +134 500 134 500 +136 1 136 1 +136 500 136 500 +138 1 138 1 +138 500 138 500 +140 1 140 1 +140 500 140 500 +142 1 142 1 +142 500 142 500 +144 1 144 1 +144 500 144 500 +146 1 146 1 +146 500 146 500 +148 1 148 1 +148 500 148 500 +150 1 150 1 +150 500 150 500 +152 1 152 1 +152 500 152 500 +154 1 154 1 +154 500 154 500 +156 1 156 1 +156 500 156 500 +158 1 158 1 +158 500 158 500 +160 1 160 1 +160 500 160 500 +162 1 162 1 +162 500 162 500 +164 1 164 1 +164 500 164 500 +166 1 166 1 +166 500 166 500 +168 1 168 1 +168 500 168 500 +170 1 170 1 +170 500 170 500 +172 1 172 1 +172 500 172 500 +174 1 174 1 +174 500 174 500 +176 1 176 1 +176 500 176 500 +178 1 178 1 +178 500 178 500 +180 1 180 1 +180 500 180 500 +182 1 182 1 +182 500 182 500 +184 1 184 1 +184 500 184 500 +186 1 186 1 +186 500 186 500 +188 1 188 1 +188 500 188 500 +190 1 190 1 +190 500 190 500 +192 1 192 1 +192 500 192 500 +194 1 194 1 +194 500 194 500 +196 1 196 1 +196 500 196 500 +198 1 198 1 +198 500 198 500 +200 1 200 1 +200 500 200 500 +202 1 202 1 +202 500 202 500 +204 1 204 1 +204 500 204 500 +206 1 206 1 +206 500 206 500 +208 1 208 1 +208 500 208 500 +210 1 210 1 +210 500 210 500 +212 1 212 1 +212 500 212 500 +214 1 214 1 +214 500 214 500 +216 1 216 1 +216 500 216 500 +218 1 218 1 +218 500 218 500 +220 1 220 1 +220 500 220 500 +222 1 222 1 +222 500 222 500 +224 1 224 1 +224 500 224 500 +226 1 226 1 +226 500 226 500 +228 1 228 1 +228 500 228 500 +230 1 230 1 +230 500 230 500 +232 1 232 1 +232 500 232 500 +234 1 234 1 +234 500 234 500 +236 1 236 1 +236 500 236 500 +238 1 238 1 +238 500 238 500 +240 1 240 1 +240 500 240 500 +242 1 242 1 +242 500 242 500 +244 1 244 1 +244 500 244 500 +246 1 246 1 +246 500 246 500 +248 1 248 1 +248 500 248 500 +250 1 250 1 +250 500 250 500 +252 1 252 1 +252 500 252 500 +254 1 254 1 +254 500 254 500 +256 1 256 1 +256 500 256 500 +258 1 258 1 +258 500 258 500 +260 1 260 1 +260 500 260 500 +262 1 262 1 +262 500 262 500 +264 1 264 1 +264 500 264 500 +266 1 266 1 +266 500 266 500 +268 1 268 1 +268 500 268 500 +270 1 270 1 +270 500 270 500 +272 1 272 1 +272 500 272 500 +274 1 274 1 +274 500 274 500 +276 1 276 1 +276 500 276 500 +278 1 278 1 +278 500 278 500 +280 1 280 1 +280 500 280 500 +282 1 282 1 +282 500 282 500 +284 1 284 1 +284 500 284 500 +286 1 286 1 +286 500 286 500 +288 1 288 1 +288 500 288 500 +290 1 290 1 +290 500 290 500 +292 1 292 1 +292 500 292 500 +294 1 294 1 +294 500 294 500 +296 1 296 1 +296 500 296 500 +298 1 298 1 +298 500 298 500 +300 1 300 1 +300 500 300 500 +302 1 302 1 +302 500 302 500 +304 1 304 1 +304 500 304 500 +306 1 306 1 +306 500 306 500 +308 1 308 1 +308 500 308 500 +310 1 310 1 +310 500 310 500 +312 1 312 1 +312 500 312 500 +314 1 314 1 +314 500 314 500 +316 1 316 1 +316 500 316 500 +318 1 318 1 +318 500 318 500 +320 1 320 1 +320 500 320 500 +322 1 322 1 +322 500 322 500 +324 1 324 1 +324 500 324 500 +326 1 326 1 +326 500 326 500 +328 1 328 1 +328 500 328 500 +330 1 330 1 +330 500 330 500 +332 1 332 1 +332 500 332 500 +334 1 334 1 +334 500 334 500 +336 1 336 1 +336 500 336 500 +338 1 338 1 +338 500 338 500 +340 1 340 1 +340 500 340 500 +342 1 342 1 +342 500 342 500 +344 1 344 1 +344 500 344 500 +346 1 346 1 +346 500 346 500 +348 1 348 1 +348 500 348 500 +350 1 350 1 +350 500 350 500 +352 1 352 1 +352 500 352 500 +354 1 354 1 +354 500 354 500 +356 1 356 1 +356 500 356 500 +358 1 358 1 +358 500 358 500 +360 1 360 1 +360 500 360 500 +362 1 362 1 +362 500 362 500 +364 1 364 1 +364 500 364 500 +366 1 366 1 +366 500 366 500 +368 1 368 1 +368 500 368 500 +370 1 370 1 +370 500 370 500 +372 1 372 1 +372 500 372 500 +374 1 374 1 +374 500 374 500 +376 1 376 1 +376 500 376 500 +378 1 378 1 +378 500 378 500 +380 1 380 1 +380 500 380 500 +382 1 382 1 +382 500 382 500 +384 1 384 1 +384 500 384 500 +386 1 386 1 +386 500 386 500 +388 1 388 1 +388 500 388 500 +390 1 390 1 +390 500 390 500 +392 1 392 1 +392 500 392 500 +394 1 394 1 +394 500 394 500 +396 1 396 1 +396 500 396 500 +398 1 398 1 +398 500 398 500 +400 1 400 1 +400 500 400 500 +402 1 402 1 +402 500 402 500 +404 1 404 1 +404 500 404 500 +406 1 406 1 +406 500 406 500 +408 1 408 1 +408 500 408 500 +410 1 410 1 +410 500 410 500 +412 1 412 1 +412 500 412 500 +414 1 414 1 +414 500 414 500 +416 1 416 1 +416 500 416 500 +418 1 418 1 +418 500 418 500 +420 1 420 1 +420 500 420 500 +422 1 422 1 +422 500 422 500 +424 1 424 1 +424 500 424 500 +426 1 426 1 +426 500 426 500 +428 1 428 1 +428 500 428 500 +430 1 430 1 +430 500 430 500 +432 1 432 1 +432 500 432 500 +434 1 434 1 +434 500 434 500 +436 1 436 1 +436 500 436 500 +438 1 438 1 +438 500 438 500 +440 1 440 1 +440 500 440 500 +442 1 442 1 +442 500 442 500 +444 1 444 1 +444 500 444 500 +446 1 446 1 +446 500 446 500 +448 1 448 1 +448 500 448 500 +450 1 450 1 +450 500 450 500 +452 1 452 1 +452 500 452 500 +454 1 454 1 +454 500 454 500 +456 1 456 1 +456 500 456 500 +458 1 458 1 +458 500 458 500 +460 1 460 1 +460 500 460 500 +462 1 462 1 +462 500 462 500 +464 1 464 1 +464 500 464 500 +466 1 466 1 +466 500 466 500 +468 1 468 1 +468 500 468 500 +470 1 470 1 +470 500 470 500 +472 1 472 1 +472 500 472 500 +474 1 474 1 +474 500 474 500 +476 1 476 1 +476 500 476 500 +478 1 478 1 +478 500 478 500 +480 1 480 1 +480 500 480 500 +482 1 482 1 +482 500 482 500 +484 1 484 1 +484 500 484 500 +486 1 486 1 +486 500 486 500 +488 1 488 1 +488 500 488 500 +490 1 490 1 +490 500 490 500 +492 1 492 1 +492 500 492 500 +494 1 494 1 +494 500 494 500 +496 1 496 1 +496 500 496 500 +498 1 498 1 +498 500 498 500 +1 2 1 2 +500 2 500 2 +1 4 1 4 +500 4 500 4 +1 6 1 6 +500 6 500 6 +1 8 1 8 +500 8 500 8 +1 10 1 10 +500 10 500 10 +1 12 1 12 +500 12 500 12 +1 14 1 14 +500 14 500 14 +1 16 1 16 +500 16 500 16 +1 18 1 18 +500 18 500 18 +1 20 1 20 +500 20 500 20 +1 22 1 22 +500 22 500 22 +1 24 1 24 +500 24 500 24 +1 26 1 26 +500 26 500 26 +1 28 1 28 +500 28 500 28 +1 30 1 30 +500 30 500 30 +1 32 1 32 +500 32 500 32 +1 34 1 34 +500 34 500 34 +1 36 1 36 +500 36 500 36 +1 38 1 38 +500 38 500 38 +1 40 1 40 +500 40 500 40 +1 42 1 42 +500 42 500 42 +1 44 1 44 +500 44 500 44 +1 46 1 46 +500 46 500 46 +1 48 1 48 +500 48 500 48 +1 50 1 50 +500 50 500 50 +1 52 1 52 +500 52 500 52 +1 54 1 54 +500 54 500 54 +1 56 1 56 +500 56 500 56 +1 58 1 58 +500 58 500 58 +1 60 1 60 +500 60 500 60 +1 62 1 62 +500 62 500 62 +1 64 1 64 +500 64 500 64 +1 66 1 66 +500 66 500 66 +1 68 1 68 +500 68 500 68 +1 70 1 70 +500 70 500 70 +1 72 1 72 +500 72 500 72 +1 74 1 74 +500 74 500 74 +1 76 1 76 +500 76 500 76 +1 78 1 78 +500 78 500 78 +1 80 1 80 +500 80 500 80 +1 82 1 82 +500 82 500 82 +1 84 1 84 +500 84 500 84 +1 86 1 86 +500 86 500 86 +1 88 1 88 +500 88 500 88 +1 90 1 90 +500 90 500 90 +1 92 1 92 +500 92 500 92 +1 94 1 94 +500 94 500 94 +1 96 1 96 +500 96 500 96 +1 98 1 98 +500 98 500 98 +1 100 1 100 +500 100 500 100 +1 102 1 102 +500 102 500 102 +1 104 1 104 +500 104 500 104 +1 106 1 106 +500 106 500 106 +1 108 1 108 +500 108 500 108 +1 110 1 110 +500 110 500 110 +1 112 1 112 +500 112 500 112 +1 114 1 114 +500 114 500 114 +1 116 1 116 +500 116 500 116 +1 118 1 118 +500 118 500 118 +1 120 1 120 +500 120 500 120 +1 122 1 122 +500 122 500 122 +1 124 1 124 +500 124 500 124 +1 126 1 126 +500 126 500 126 +1 128 1 128 +500 128 500 128 +1 130 1 130 +500 130 500 130 +1 132 1 132 +500 132 500 132 +1 134 1 134 +500 134 500 134 +1 136 1 136 +500 136 500 136 +1 138 1 138 +500 138 500 138 +1 140 1 140 +500 140 500 140 +1 142 1 142 +500 142 500 142 +1 144 1 144 +500 144 500 144 +1 146 1 146 +500 146 500 146 +1 148 1 148 +500 148 500 148 +1 150 1 150 +500 150 500 150 +1 152 1 152 +500 152 500 152 +1 154 1 154 +500 154 500 154 +1 156 1 156 +500 156 500 156 +1 158 1 158 +500 158 500 158 +1 160 1 160 +500 160 500 160 +1 162 1 162 +500 162 500 162 +1 164 1 164 +500 164 500 164 +1 166 1 166 +500 166 500 166 +1 168 1 168 +500 168 500 168 +1 170 1 170 +500 170 500 170 +1 172 1 172 +500 172 500 172 +1 174 1 174 +500 174 500 174 +1 176 1 176 +500 176 500 176 +1 178 1 178 +500 178 500 178 +1 180 1 180 +500 180 500 180 +1 182 1 182 +500 182 500 182 +1 184 1 184 +500 184 500 184 +1 186 1 186 +500 186 500 186 +1 188 1 188 +500 188 500 188 +1 190 1 190 +500 190 500 190 +1 192 1 192 +500 192 500 192 +1 194 1 194 +500 194 500 194 +1 196 1 196 +500 196 500 196 +1 198 1 198 +500 198 500 198 +1 200 1 200 +500 200 500 200 +1 202 1 202 +500 202 500 202 +1 204 1 204 +500 204 500 204 +1 206 1 206 +500 206 500 206 +1 208 1 208 +500 208 500 208 +1 210 1 210 +500 210 500 210 +1 212 1 212 +500 212 500 212 +1 214 1 214 +500 214 500 214 +1 216 1 216 +500 216 500 216 +1 218 1 218 +500 218 500 218 +1 220 1 220 +500 220 500 220 +1 222 1 222 +500 222 500 222 +1 224 1 224 +500 224 500 224 +1 226 1 226 +500 226 500 226 +1 228 1 228 +500 228 500 228 +1 230 1 230 +500 230 500 230 +1 232 1 232 +500 232 500 232 +1 234 1 234 +500 234 500 234 +1 236 1 236 +500 236 500 236 +1 238 1 238 +500 238 500 238 +1 240 1 240 +500 240 500 240 +1 242 1 242 +500 242 500 242 +1 244 1 244 +500 244 500 244 +1 246 1 246 +500 246 500 246 +1 248 1 248 +500 248 500 248 +1 250 1 250 +500 250 500 250 +1 252 1 252 +500 252 500 252 +1 254 1 254 +500 254 500 254 +1 256 1 256 +500 256 500 256 +1 258 1 258 +500 258 500 258 +1 260 1 260 +500 260 500 260 +1 262 1 262 +500 262 500 262 +1 264 1 264 +500 264 500 264 +1 266 1 266 +500 266 500 266 +1 268 1 268 +500 268 500 268 +1 270 1 270 +500 270 500 270 +1 272 1 272 +500 272 500 272 +1 274 1 274 +500 274 500 274 +1 276 1 276 +500 276 500 276 +1 278 1 278 +500 278 500 278 +1 280 1 280 +500 280 500 280 +1 282 1 282 +500 282 500 282 +1 284 1 284 +500 284 500 284 +1 286 1 286 +500 286 500 286 +1 288 1 288 +500 288 500 288 +1 290 1 290 +500 290 500 290 +1 292 1 292 +500 292 500 292 +1 294 1 294 +500 294 500 294 +1 296 1 296 +500 296 500 296 +1 298 1 298 +500 298 500 298 +1 300 1 300 +500 300 500 300 +1 302 1 302 +500 302 500 302 +1 304 1 304 +500 304 500 304 +1 306 1 306 +500 306 500 306 +1 308 1 308 +500 308 500 308 +1 310 1 310 +500 310 500 310 +1 312 1 312 +500 312 500 312 +1 314 1 314 +500 314 500 314 +1 316 1 316 +500 316 500 316 +1 318 1 318 +500 318 500 318 +1 320 1 320 +500 320 500 320 +1 322 1 322 +500 322 500 322 +1 324 1 324 +500 324 500 324 +1 326 1 326 +500 326 500 326 +1 328 1 328 +500 328 500 328 +1 330 1 330 +500 330 500 330 +1 332 1 332 +500 332 500 332 +1 334 1 334 +500 334 500 334 +1 336 1 336 +500 336 500 336 +1 338 1 338 +500 338 500 338 +1 340 1 340 +500 340 500 340 +1 342 1 342 +500 342 500 342 +1 344 1 344 +500 344 500 344 +1 346 1 346 +500 346 500 346 +1 348 1 348 +500 348 500 348 +1 350 1 350 +500 350 500 350 +1 352 1 352 +500 352 500 352 +1 354 1 354 +500 354 500 354 +1 356 1 356 +500 356 500 356 +1 358 1 358 +500 358 500 358 +1 360 1 360 +500 360 500 360 +1 362 1 362 +500 362 500 362 +1 364 1 364 +500 364 500 364 +1 366 1 366 +500 366 500 366 +1 368 1 368 +500 368 500 368 +1 370 1 370 +500 370 500 370 +1 372 1 372 +500 372 500 372 +1 374 1 374 +500 374 500 374 +1 376 1 376 +500 376 500 376 +1 378 1 378 +500 378 500 378 +1 380 1 380 +500 380 500 380 +1 382 1 382 +500 382 500 382 +1 384 1 384 +500 384 500 384 +1 386 1 386 +500 386 500 386 +1 388 1 388 +500 388 500 388 +1 390 1 390 +500 390 500 390 +1 392 1 392 +500 392 500 392 +1 394 1 394 +500 394 500 394 +1 396 1 396 +500 396 500 396 +1 398 1 398 +500 398 500 398 +1 400 1 400 +500 400 500 400 +1 402 1 402 +500 402 500 402 +1 404 1 404 +500 404 500 404 +1 406 1 406 +500 406 500 406 +1 408 1 408 +500 408 500 408 +1 410 1 410 +500 410 500 410 +1 412 1 412 +500 412 500 412 +1 414 1 414 +500 414 500 414 +1 416 1 416 +500 416 500 416 +1 418 1 418 +500 418 500 418 +1 420 1 420 +500 420 500 420 +1 422 1 422 +500 422 500 422 +1 424 1 424 +500 424 500 424 +1 426 1 426 +500 426 500 426 +1 428 1 428 +500 428 500 428 +1 430 1 430 +500 430 500 430 +1 432 1 432 +500 432 500 432 +1 434 1 434 +500 434 500 434 +1 436 1 436 +500 436 500 436 +1 438 1 438 +500 438 500 438 +1 440 1 440 +500 440 500 440 +1 442 1 442 +500 442 500 442 +1 444 1 444 +500 444 500 444 +1 446 1 446 +500 446 500 446 +1 448 1 448 +500 448 500 448 +1 450 1 450 +500 450 500 450 +1 452 1 452 +500 452 500 452 +1 454 1 454 +500 454 500 454 +1 456 1 456 +500 456 500 456 +1 458 1 458 +500 458 500 458 +1 460 1 460 +500 460 500 460 +1 462 1 462 +500 462 500 462 +1 464 1 464 +500 464 500 464 +1 466 1 466 +500 466 500 466 +1 468 1 468 +500 468 500 468 +1 470 1 470 +500 470 500 470 +1 472 1 472 +500 472 500 472 +1 474 1 474 +500 474 500 474 +1 476 1 476 +500 476 500 476 +1 478 1 478 +500 478 500 478 +1 480 1 480 +500 480 500 480 +1 482 1 482 +500 482 500 482 +1 484 1 484 +500 484 500 484 +1 486 1 486 +500 486 500 486 +1 488 1 488 +500 488 500 488 +1 490 1 490 +500 490 500 490 +1 492 1 492 +500 492 500 492 +1 494 1 494 +500 494 500 494 +1 496 1 496 +500 496 500 496 +1 498 1 498 +500 498 500 498 +500 500 +1 1 500 500 +166 +2 2 3 500 +5 1 6 499 +8 2 9 500 +11 1 12 499 +14 2 15 500 +17 1 18 499 +20 2 21 500 +23 1 24 499 +26 2 27 500 +29 1 30 499 +32 2 33 500 +35 1 36 499 +38 2 39 500 +41 1 42 499 +44 2 45 500 +47 1 48 499 +50 2 51 500 +53 1 54 499 +56 2 57 500 +59 1 60 499 +62 2 63 500 +65 1 66 499 +68 2 69 500 +71 1 72 499 +74 2 75 500 +77 1 78 499 +80 2 81 500 +83 1 84 499 +86 2 87 500 +89 1 90 499 +92 2 93 500 +95 1 96 499 +98 2 99 500 +101 1 102 499 +104 2 105 500 +107 1 108 499 +110 2 111 500 +113 1 114 499 +116 2 117 500 +119 1 120 499 +122 2 123 500 +125 1 126 499 +128 2 129 500 +131 1 132 499 +134 2 135 500 +137 1 138 499 +140 2 141 500 +143 1 144 499 +146 2 147 500 +149 1 150 499 +152 2 153 500 +155 1 156 499 +158 2 159 500 +161 1 162 499 +164 2 165 500 +167 1 168 499 +170 2 171 500 +173 1 174 499 +176 2 177 500 +179 1 180 499 +182 2 183 500 +185 1 186 499 +188 2 189 500 +191 1 192 499 +194 2 195 500 +197 1 198 499 +200 2 201 500 +203 1 204 499 +206 2 207 500 +209 1 210 499 +212 2 213 500 +215 1 216 499 +218 2 219 500 +221 1 222 499 +224 2 225 500 +227 1 228 499 +230 2 231 500 +233 1 234 499 +236 2 237 500 +239 1 240 499 +242 2 243 500 +245 1 246 499 +248 2 249 500 +251 1 252 499 +254 2 255 500 +257 1 258 499 +260 2 261 500 +263 1 264 499 +266 2 267 500 +269 1 270 499 +272 2 273 500 +275 1 276 499 +278 2 279 500 +281 1 282 499 +284 2 285 500 +287 1 288 499 +290 2 291 500 +293 1 294 499 +296 2 297 500 +299 1 300 499 +302 2 303 500 +305 1 306 499 +308 2 309 500 +311 1 312 499 +314 2 315 500 +317 1 318 499 +320 2 321 500 +323 1 324 499 +326 2 327 500 +329 1 330 499 +332 2 333 500 +335 1 336 499 +338 2 339 500 +341 1 342 499 +344 2 345 500 +347 1 348 499 +350 2 351 500 +353 1 354 499 +356 2 357 500 +359 1 360 499 +362 2 363 500 +365 1 366 499 +368 2 369 500 +371 1 372 499 +374 2 375 500 +377 1 378 499 +380 2 381 500 +383 1 384 499 +386 2 387 500 +389 1 390 499 +392 2 393 500 +395 1 396 499 +398 2 399 500 +401 1 402 499 +404 2 405 500 +407 1 408 499 +410 2 411 500 +413 1 414 499 +416 2 417 500 +419 1 420 499 +422 2 423 500 +425 1 426 499 +428 2 429 500 +431 1 432 499 +434 2 435 500 +437 1 438 499 +440 2 441 500 +443 1 444 499 +446 2 447 500 +449 1 450 499 +452 2 453 500 +455 1 456 499 +458 2 459 500 +461 1 462 499 +464 2 465 500 +467 1 468 499 +470 2 471 500 +473 1 474 499 +476 2 477 500 +479 1 480 499 +482 2 483 500 +485 1 486 499 +488 2 489 500 +491 1 492 499 +494 2 495 500 +497 1 498 499 +500 500 +1 1 250 250 +252 +2 2 499 2 +2 499 499 499 +2 3 2 498 +499 3 499 498 +4 4 497 4 +4 497 497 497 +4 5 4 496 +497 5 497 496 +6 6 495 6 +6 495 495 495 +6 7 6 494 +495 7 495 494 +8 8 493 8 +8 493 493 493 +8 9 8 492 +493 9 493 492 +10 10 491 10 +10 491 491 491 +10 11 10 490 +491 11 491 490 +12 12 489 12 +12 489 489 489 +12 13 12 488 +489 13 489 488 +14 14 487 14 +14 487 487 487 +14 15 14 486 +487 15 487 486 +16 16 485 16 +16 485 485 485 +16 17 16 484 +485 17 485 484 +18 18 483 18 +18 483 483 483 +18 19 18 482 +483 19 483 482 +20 20 481 20 +20 481 481 481 +20 21 20 480 +481 21 481 480 +22 22 479 22 +22 479 479 479 +22 23 22 478 +479 23 479 478 +24 24 477 24 +24 477 477 477 +24 25 24 476 +477 25 477 476 +26 26 475 26 +26 475 475 475 +26 27 26 474 +475 27 475 474 +28 28 473 28 +28 473 473 473 +28 29 28 472 +473 29 473 472 +30 30 471 30 +30 471 471 471 +30 31 30 470 +471 31 471 470 +32 32 469 32 +32 469 469 469 +32 33 32 468 +469 33 469 468 +34 34 467 34 +34 467 467 467 +34 35 34 466 +467 35 467 466 +36 36 465 36 +36 465 465 465 +36 37 36 464 +465 37 465 464 +38 38 463 38 +38 463 463 463 +38 39 38 462 +463 39 463 462 +40 40 461 40 +40 461 461 461 +40 41 40 460 +461 41 461 460 +42 42 459 42 +42 459 459 459 +42 43 42 458 +459 43 459 458 +44 44 457 44 +44 457 457 457 +44 45 44 456 +457 45 457 456 +46 46 455 46 +46 455 455 455 +46 47 46 454 +455 47 455 454 +48 48 453 48 +48 453 453 453 +48 49 48 452 +453 49 453 452 +50 50 451 50 +50 451 451 451 +50 51 50 450 +451 51 451 450 +52 52 449 52 +52 449 449 449 +52 53 52 448 +449 53 449 448 +54 54 447 54 +54 447 447 447 +54 55 54 446 +447 55 447 446 +56 56 445 56 +56 445 445 445 +56 57 56 444 +445 57 445 444 +58 58 443 58 +58 443 443 443 +58 59 58 442 +443 59 443 442 +60 60 441 60 +60 441 441 441 +60 61 60 440 +441 61 441 440 +62 62 439 62 +62 439 439 439 +62 63 62 438 +439 63 439 438 +64 64 437 64 +64 437 437 437 +64 65 64 436 +437 65 437 436 +66 66 435 66 +66 435 435 435 +66 67 66 434 +435 67 435 434 +68 68 433 68 +68 433 433 433 +68 69 68 432 +433 69 433 432 +70 70 431 70 +70 431 431 431 +70 71 70 430 +431 71 431 430 +72 72 429 72 +72 429 429 429 +72 73 72 428 +429 73 429 428 +74 74 427 74 +74 427 427 427 +74 75 74 426 +427 75 427 426 +76 76 425 76 +76 425 425 425 +76 77 76 424 +425 77 425 424 +78 78 423 78 +78 423 423 423 +78 79 78 422 +423 79 423 422 +80 80 421 80 +80 421 421 421 +80 81 80 420 +421 81 421 420 +82 82 419 82 +82 419 419 419 +82 83 82 418 +419 83 419 418 +84 84 417 84 +84 417 417 417 +84 85 84 416 +417 85 417 416 +86 86 415 86 +86 415 415 415 +86 87 86 414 +415 87 415 414 +88 88 413 88 +88 413 413 413 +88 89 88 412 +413 89 413 412 +90 90 411 90 +90 411 411 411 +90 91 90 410 +411 91 411 410 +92 92 409 92 +92 409 409 409 +92 93 92 408 +409 93 409 408 +94 94 407 94 +94 407 407 407 +94 95 94 406 +407 95 407 406 +96 96 405 96 +96 405 405 405 +96 97 96 404 +405 97 405 404 +98 98 403 98 +98 403 403 403 +98 99 98 402 +403 99 403 402 +100 100 401 100 +100 401 401 401 +100 101 100 400 +401 101 401 400 +102 102 399 102 +102 399 399 399 +102 103 102 398 +399 103 399 398 +104 104 397 104 +104 397 397 397 +104 105 104 396 +397 105 397 396 +106 106 395 106 +106 395 395 395 +106 107 106 394 +395 107 395 394 +108 108 393 108 +108 393 393 393 +108 109 108 392 +393 109 393 392 +110 110 391 110 +110 391 391 391 +110 111 110 390 +391 111 391 390 +112 112 389 112 +112 389 389 389 +112 113 112 388 +389 113 389 388 +114 114 387 114 +114 387 387 387 +114 115 114 386 +387 115 387 386 +116 116 385 116 +116 385 385 385 +116 117 116 384 +385 117 385 384 +118 118 383 118 +118 383 383 383 +118 119 118 382 +383 119 383 382 +120 120 381 120 +120 381 381 381 +120 121 120 380 +381 121 381 380 +122 122 379 122 +122 379 379 379 +122 123 122 378 +379 123 379 378 +124 124 377 124 +124 377 377 377 +124 125 124 376 +377 125 377 376 +126 126 375 126 +126 375 375 375 +126 127 126 374 +375 127 375 374 +500 500 +1 1 250 250 +224 +2 2 499 3 +2 498 499 499 +2 4 3 497 +498 4 499 497 +5 5 496 6 +5 495 496 496 +5 7 6 494 +495 7 496 494 +8 8 493 9 +8 492 493 493 +8 10 9 491 +492 10 493 491 +11 11 490 12 +11 489 490 490 +11 13 12 488 +489 13 490 488 +14 14 487 15 +14 486 487 487 +14 16 15 485 +486 16 487 485 +17 17 484 18 +17 483 484 484 +17 19 18 482 +483 19 484 482 +20 20 481 21 +20 480 481 481 +20 22 21 479 +480 22 481 479 +23 23 478 24 +23 477 478 478 +23 25 24 476 +477 25 478 476 +26 26 475 27 +26 474 475 475 +26 28 27 473 +474 28 475 473 +29 29 472 30 +29 471 472 472 +29 31 30 470 +471 31 472 470 +32 32 469 33 +32 468 469 469 +32 34 33 467 +468 34 469 467 +35 35 466 36 +35 465 466 466 +35 37 36 464 +465 37 466 464 +38 38 463 39 +38 462 463 463 +38 40 39 461 +462 40 463 461 +41 41 460 42 +41 459 460 460 +41 43 42 458 +459 43 460 458 +44 44 457 45 +44 456 457 457 +44 46 45 455 +456 46 457 455 +47 47 454 48 +47 453 454 454 +47 49 48 452 +453 49 454 452 +50 50 451 51 +50 450 451 451 +50 52 51 449 +450 52 451 449 +53 53 448 54 +53 447 448 448 +53 55 54 446 +447 55 448 446 +56 56 445 57 +56 444 445 445 +56 58 57 443 +444 58 445 443 +59 59 442 60 +59 441 442 442 +59 61 60 440 +441 61 442 440 +62 62 439 63 +62 438 439 439 +62 64 63 437 +438 64 439 437 +65 65 436 66 +65 435 436 436 +65 67 66 434 +435 67 436 434 +68 68 433 69 +68 432 433 433 +68 70 69 431 +432 70 433 431 +71 71 430 72 +71 429 430 430 +71 73 72 428 +429 73 430 428 +74 74 427 75 +74 426 427 427 +74 76 75 425 +426 76 427 425 +77 77 424 78 +77 423 424 424 +77 79 78 422 +423 79 424 422 +80 80 421 81 +80 420 421 421 +80 82 81 419 +420 82 421 419 +83 83 418 84 +83 417 418 418 +83 85 84 416 +417 85 418 416 +86 86 415 87 +86 414 415 415 +86 88 87 413 +414 88 415 413 +89 89 412 90 +89 411 412 412 +89 91 90 410 +411 91 412 410 +92 92 409 93 +92 408 409 409 +92 94 93 407 +408 94 409 407 +95 95 406 96 +95 405 406 406 +95 97 96 404 +405 97 406 404 +98 98 403 99 +98 402 403 403 +98 100 99 401 +402 100 403 401 +101 101 400 102 +101 399 400 400 +101 103 102 398 +399 103 400 398 +104 104 397 105 +104 396 397 397 +104 106 105 395 +396 106 397 395 +107 107 394 108 +107 393 394 394 +107 109 108 392 +393 109 394 392 +110 110 391 111 +110 390 391 391 +110 112 111 389 +390 112 391 389 +113 113 388 114 +113 387 388 388 +113 115 114 386 +387 115 388 386 +116 116 385 117 +116 384 385 385 +116 118 117 383 +384 118 385 383 +119 119 382 120 +119 381 382 382 +119 121 120 380 +381 121 382 380 +122 122 379 123 +122 378 379 379 +122 124 123 377 +378 124 379 377 +125 125 376 126 +125 375 376 376 +125 127 126 374 +375 127 376 374 +128 128 373 129 +128 372 373 373 +128 130 129 371 +372 130 373 371 +131 131 370 132 +131 369 370 370 +131 133 132 368 +369 133 370 368 +134 134 367 135 +134 366 367 367 +134 136 135 365 +366 136 367 365 +137 137 364 138 +137 363 364 364 +137 139 138 362 +363 139 364 362 +140 140 361 141 +140 360 361 361 +140 142 141 359 +360 142 361 359 +143 143 358 144 +143 357 358 358 +143 145 144 356 +357 145 358 356 +146 146 355 147 +146 354 355 355 +146 148 147 353 +354 148 355 353 +149 149 352 150 +149 351 352 352 +149 151 150 350 +351 151 352 350 +152 152 349 153 +152 348 349 349 +152 154 153 347 +348 154 349 347 +155 155 346 156 +155 345 346 346 +155 157 156 344 +345 157 346 344 +158 158 343 159 +158 342 343 343 +158 160 159 341 +342 160 343 341 +161 161 340 162 +161 339 340 340 +161 163 162 338 +339 163 340 338 +164 164 337 165 +164 336 337 337 +164 166 165 335 +336 166 337 335 +167 167 334 168 +167 333 334 334 +167 169 168 332 +333 169 334 332 +1000 1000 +1 1 1000 1000 +332 +2 2 1000 3 +1 5 999 6 +2 8 1000 9 +1 11 999 12 +2 14 1000 15 +1 17 999 18 +2 20 1000 21 +1 23 999 24 +2 26 1000 27 +1 29 999 30 +2 32 1000 33 +1 35 999 36 +2 38 1000 39 +1 41 999 42 +2 44 1000 45 +1 47 999 48 +2 50 1000 51 +1 53 999 54 +2 56 1000 57 +1 59 999 60 +2 62 1000 63 +1 65 999 66 +2 68 1000 69 +1 71 999 72 +2 74 1000 75 +1 77 999 78 +2 80 1000 81 +1 83 999 84 +2 86 1000 87 +1 89 999 90 +2 92 1000 93 +1 95 999 96 +2 98 1000 99 +1 101 999 102 +2 104 1000 105 +1 107 999 108 +2 110 1000 111 +1 113 999 114 +2 116 1000 117 +1 119 999 120 +2 122 1000 123 +1 125 999 126 +2 128 1000 129 +1 131 999 132 +2 134 1000 135 +1 137 999 138 +2 140 1000 141 +1 143 999 144 +2 146 1000 147 +1 149 999 150 +2 152 1000 153 +1 155 999 156 +2 158 1000 159 +1 161 999 162 +2 164 1000 165 +1 167 999 168 +2 170 1000 171 +1 173 999 174 +2 176 1000 177 +1 179 999 180 +2 182 1000 183 +1 185 999 186 +2 188 1000 189 +1 191 999 192 +2 194 1000 195 +1 197 999 198 +2 200 1000 201 +1 203 999 204 +2 206 1000 207 +1 209 999 210 +2 212 1000 213 +1 215 999 216 +2 218 1000 219 +1 221 999 222 +2 224 1000 225 +1 227 999 228 +2 230 1000 231 +1 233 999 234 +2 236 1000 237 +1 239 999 240 +2 242 1000 243 +1 245 999 246 +2 248 1000 249 +1 251 999 252 +2 254 1000 255 +1 257 999 258 +2 260 1000 261 +1 263 999 264 +2 266 1000 267 +1 269 999 270 +2 272 1000 273 +1 275 999 276 +2 278 1000 279 +1 281 999 282 +2 284 1000 285 +1 287 999 288 +2 290 1000 291 +1 293 999 294 +2 296 1000 297 +1 299 999 300 +2 302 1000 303 +1 305 999 306 +2 308 1000 309 +1 311 999 312 +2 314 1000 315 +1 317 999 318 +2 320 1000 321 +1 323 999 324 +2 326 1000 327 +1 329 999 330 +2 332 1000 333 +1 335 999 336 +2 338 1000 339 +1 341 999 342 +2 344 1000 345 +1 347 999 348 +2 350 1000 351 +1 353 999 354 +2 356 1000 357 +1 359 999 360 +2 362 1000 363 +1 365 999 366 +2 368 1000 369 +1 371 999 372 +2 374 1000 375 +1 377 999 378 +2 380 1000 381 +1 383 999 384 +2 386 1000 387 +1 389 999 390 +2 392 1000 393 +1 395 999 396 +2 398 1000 399 +1 401 999 402 +2 404 1000 405 +1 407 999 408 +2 410 1000 411 +1 413 999 414 +2 416 1000 417 +1 419 999 420 +2 422 1000 423 +1 425 999 426 +2 428 1000 429 +1 431 999 432 +2 434 1000 435 +1 437 999 438 +2 440 1000 441 +1 443 999 444 +2 446 1000 447 +1 449 999 450 +2 452 1000 453 +1 455 999 456 +2 458 1000 459 +1 461 999 462 +2 464 1000 465 +1 467 999 468 +2 470 1000 471 +1 473 999 474 +2 476 1000 477 +1 479 999 480 +2 482 1000 483 +1 485 999 486 +2 488 1000 489 +1 491 999 492 +2 494 1000 495 +1 497 999 498 +2 500 1000 501 +1 503 999 504 +2 506 1000 507 +1 509 999 510 +2 512 1000 513 +1 515 999 516 +2 518 1000 519 +1 521 999 522 +2 524 1000 525 +1 527 999 528 +2 530 1000 531 +1 533 999 534 +2 536 1000 537 +1 539 999 540 +2 542 1000 543 +1 545 999 546 +2 548 1000 549 +1 551 999 552 +2 554 1000 555 +1 557 999 558 +2 560 1000 561 +1 563 999 564 +2 566 1000 567 +1 569 999 570 +2 572 1000 573 +1 575 999 576 +2 578 1000 579 +1 581 999 582 +2 584 1000 585 +1 587 999 588 +2 590 1000 591 +1 593 999 594 +2 596 1000 597 +1 599 999 600 +2 602 1000 603 +1 605 999 606 +2 608 1000 609 +1 611 999 612 +2 614 1000 615 +1 617 999 618 +2 620 1000 621 +1 623 999 624 +2 626 1000 627 +1 629 999 630 +2 632 1000 633 +1 635 999 636 +2 638 1000 639 +1 641 999 642 +2 644 1000 645 +1 647 999 648 +2 650 1000 651 +1 653 999 654 +2 656 1000 657 +1 659 999 660 +2 662 1000 663 +1 665 999 666 +2 668 1000 669 +1 671 999 672 +2 674 1000 675 +1 677 999 678 +2 680 1000 681 +1 683 999 684 +2 686 1000 687 +1 689 999 690 +2 692 1000 693 +1 695 999 696 +2 698 1000 699 +1 701 999 702 +2 704 1000 705 +1 707 999 708 +2 710 1000 711 +1 713 999 714 +2 716 1000 717 +1 719 999 720 +2 722 1000 723 +1 725 999 726 +2 728 1000 729 +1 731 999 732 +2 734 1000 735 +1 737 999 738 +2 740 1000 741 +1 743 999 744 +2 746 1000 747 +1 749 999 750 +2 752 1000 753 +1 755 999 756 +2 758 1000 759 +1 761 999 762 +2 764 1000 765 +1 767 999 768 +2 770 1000 771 +1 773 999 774 +2 776 1000 777 +1 779 999 780 +2 782 1000 783 +1 785 999 786 +2 788 1000 789 +1 791 999 792 +2 794 1000 795 +1 797 999 798 +2 800 1000 801 +1 803 999 804 +2 806 1000 807 +1 809 999 810 +2 812 1000 813 +1 815 999 816 +2 818 1000 819 +1 821 999 822 +2 824 1000 825 +1 827 999 828 +2 830 1000 831 +1 833 999 834 +2 836 1000 837 +1 839 999 840 +2 842 1000 843 +1 845 999 846 +2 848 1000 849 +1 851 999 852 +2 854 1000 855 +1 857 999 858 +2 860 1000 861 +1 863 999 864 +2 866 1000 867 +1 869 999 870 +2 872 1000 873 +1 875 999 876 +2 878 1000 879 +1 881 999 882 +2 884 1000 885 +1 887 999 888 +2 890 1000 891 +1 893 999 894 +2 896 1000 897 +1 899 999 900 +2 902 1000 903 +1 905 999 906 +2 908 1000 909 +1 911 999 912 +2 914 1000 915 +1 917 999 918 +2 920 1000 921 +1 923 999 924 +2 926 1000 927 +1 929 999 930 +2 932 1000 933 +1 935 999 936 +2 938 1000 939 +1 941 999 942 +2 944 1000 945 +1 947 999 948 +2 950 1000 951 +1 953 999 954 +2 956 1000 957 +1 959 999 960 +2 962 1000 963 +1 965 999 966 +2 968 1000 969 +1 971 999 972 +2 974 1000 975 +1 977 999 978 +2 980 1000 981 +1 983 999 984 +2 986 1000 987 +1 989 999 990 +2 992 1000 993 +1 995 999 996 +1000 1000 +1000 1000 1 1 +0 +1000 1000 +1 1 1000 1000 +50 +343 245 502 360 +268 853 447 1000 +931 954 931 954 +298 651 330 826 +872 630 950 768 +937 747 1000 806 +956 462 1000 511 +563 317 731 347 +538 74 622 250 +960 9 1000 84 +405 407 432 507 +741 779 938 934 +548 414 599 535 +420 295 586 438 +419 777 529 927 +524 294 599 342 +772 912 912 1000 +645 642 796 810 +235 526 392 623 +177 190 240 387 +586 32 671 221 +219 438 302 587 +551 917 637 1000 +393 675 532 819 +177 568 204 691 +703 494 889 607 +16 677 105 714 +815 782 835 802 +676 386 728 425 +93 345 180 457 +418 386 510 485 +753 384 882 497 +386 545 455 651 +377 284 429 423 +882 348 1000 485 +1000 475 1000 664 +316 593 365 653 +95 155 166 329 +896 473 1000 501 +385 119 514 140 +488 938 633 960 +401 262 586 362 +794 884 848 972 +405 108 452 189 +944 837 1000 876 +777 487 943 618 +855 572 936 668 +722 298 872 347 +26 281 136 385 +147 983 326 1000 +1000 1000 +1 1 1000 1000 +1000 +720 154 740 174 +327 960 347 980 +540 607 560 627 +201 768 221 788 +704 756 724 776 +397 105 417 125 +205 99 225 119 +258 247 278 267 +35 705 55 725 +79 209 99 229 +670 147 690 167 +771 115 791 135 +921 890 941 910 +171 933 191 953 +603 648 623 668 +596 38 616 58 +546 834 566 854 +702 785 722 805 +599 910 619 930 +208 31 228 51 +70 968 90 988 +855 758 875 778 +495 599 515 619 +796 94 816 114 +638 717 658 737 +641 930 661 950 +614 267 634 287 +141 249 161 269 +29 779 49 799 +608 154 628 174 +875 989 895 1000 +961 236 981 256 +21 831 41 851 +163 279 183 299 +779 903 799 923 +803 494 823 514 +872 254 892 274 +674 52 694 72 +282 637 302 657 +700 819 720 839 +670 205 690 225 +994 698 1000 718 +685 305 705 325 +540 109 560 129 +13 397 33 417 +678 427 698 447 +844 56 864 76 +24 479 44 499 +725 963 745 983 +661 85 681 105 +392 628 412 648 +230 57 250 77 +176 669 196 689 +176 141 196 161 +90 191 110 211 +681 574 701 594 +464 898 484 918 +644 824 664 844 +296 812 316 832 +429 723 449 743 +503 50 523 70 +598 583 618 603 +994 167 1000 187 +513 809 533 829 +52 442 72 462 +803 257 823 277 +38 661 58 681 +611 282 631 302 +227 60 247 80 +30 39 50 59 +431 30 451 50 +140 237 160 257 +635 707 655 727 +415 846 435 866 +376 899 396 919 +984 642 1000 662 +458 404 478 424 +109 3 129 23 +663 788 683 808 +415 656 435 676 +166 302 186 322 +30 924 50 944 +187 943 207 963 +384 94 404 114 +323 689 343 709 +216 601 236 621 +39 525 59 545 +519 546 539 566 +499 818 519 838 +362 84 382 104 +300 370 320 390 +412 840 432 860 +412 924 432 944 +640 968 660 988 +561 1 581 21 +594 932 614 952 +729 568 749 588 +599 142 619 162 +813 226 833 246 +85 183 105 203 +58 908 78 928 +763 930 783 950 +932 495 952 515 +902 531 922 551 +217 324 237 344 +157 674 177 694 +407 933 427 953 +61 354 81 374 +471 638 491 658 +282 357 302 377 +317 948 337 968 +169 912 189 932 +378 366 398 386 +581 962 601 982 +78 191 98 211 +986 579 1000 599 +492 942 512 962 +405 837 425 857 +637 279 657 299 +493 430 513 450 +474 977 494 997 +395 56 415 76 +695 362 715 382 +525 986 545 1000 +209 515 229 535 +642 103 662 123 +305 196 325 216 +373 577 393 597 +199 532 219 552 +393 942 413 962 +754 663 774 683 +949 143 969 163 +176 696 196 716 +426 950 446 970 +151 817 171 837 +80 199 100 219 +55 638 75 658 +892 111 912 131 +677 375 697 395 +746 269 766 289 +214 186 234 206 +493 937 513 957 +671 729 691 749 +45 504 65 524 +695 552 715 572 +1000 173 1000 193 +406 765 426 785 +354 824 374 844 +387 354 407 374 +572 198 592 218 +657 203 677 223 +140 764 160 784 +78 727 98 747 +923 681 943 701 +70 347 90 367 +735 932 755 952 +254 80 274 100 +117 389 137 409 +505 161 525 181 +306 294 326 314 +85 823 105 843 +182 99 202 119 +99 244 119 264 +356 947 376 967 +742 266 762 286 +695 356 715 376 +915 45 935 65 +306 104 326 124 +370 673 390 693 +703 604 723 624 +231 633 251 653 +154 558 174 578 +644 823 664 843 +44 751 64 771 +674 435 694 455 +546 628 566 648 +693 436 713 456 +461 564 481 584 +803 440 823 460 +855 662 875 682 +570 977 590 997 +593 829 613 849 +133 231 153 251 +712 35 732 55 +645 44 665 64 +883 751 903 771 +785 213 805 233 +891 162 911 182 +240 972 260 992 +613 614 633 634 +400 605 420 625 +902 131 922 151 +232 168 252 188 +409 680 429 700 +229 120 249 140 +443 122 463 142 +426 26 446 46 +360 28 380 48 +949 807 969 827 +892 2 912 22 +263 336 283 356 +778 534 798 554 +129 544 149 564 +25 493 45 513 +539 299 559 319 +147 365 167 385 +833 508 853 528 +318 135 338 155 +690 471 710 491 +214 19 234 39 +162 406 182 426 +768 17 788 37 +725 456 745 476 +164 573 184 593 +163 961 183 981 +712 101 732 121 +438 822 458 842 +216 743 236 763 +936 27 956 47 +980 76 1000 96 +553 500 573 520 +772 365 792 385 +429 899 449 919 +43 462 63 482 +199 499 219 519 +842 530 862 550 +214 422 234 442 +517 463 537 483 +197 236 217 256 +68 409 88 429 +319 190 339 210 +30 244 50 264 +326 887 346 907 +798 861 818 881 +631 237 651 257 +45 839 65 859 +275 711 295 731 +183 45 203 65 +656 894 676 914 +791 377 811 397 +796 102 816 122 +378 35 398 55 +754 540 774 560 +487 933 507 953 +62 732 82 752 +337 441 357 461 +344 728 364 748 +54 213 74 233 +396 542 416 562 +278 876 298 896 +509 86 529 106 +854 945 874 965 +316 670 336 690 +845 768 865 788 +552 952 572 972 +768 559 788 579 +711 369 731 389 +209 784 229 804 +766 368 786 388 +847 196 867 216 +82 172 102 192 +253 712 273 732 +711 859 731 879 +989 150 1000 170 +447 435 467 455 +173 113 193 133 +57 603 77 623 +941 784 961 804 +531 660 551 680 +227 681 247 701 +414 545 434 565 +410 258 430 278 +870 600 890 620 +468 103 488 123 +625 644 645 664 +457 514 477 534 +751 899 771 919 +202 978 222 998 +978 559 998 579 +385 63 405 83 +130 809 150 829 +711 264 731 284 +422 907 442 927 +112 39 132 59 +915 487 935 507 +570 379 590 399 +467 832 487 852 +792 304 812 324 +752 468 772 488 +610 468 630 488 +975 19 995 39 +757 468 777 488 +686 602 706 622 +184 69 204 89 +333 877 353 897 +546 330 566 350 +184 360 204 380 +175 35 195 55 +413 661 433 681 +983 684 1000 704 +570 186 590 206 +750 982 770 1000 +951 88 971 108 +639 104 659 124 +531 983 551 1000 +240 465 260 485 +280 503 300 523 +702 158 722 178 +935 287 955 307 +375 108 395 128 +736 14 756 34 +583 913 603 933 +656 379 676 399 +520 922 540 942 +459 127 479 147 +883 303 903 323 +594 479 614 499 +535 909 555 929 +532 114 552 134 +298 858 318 878 +992 37 1000 57 +189 599 209 619 +188 813 208 833 +864 72 884 92 +454 583 474 603 +358 701 378 721 +936 76 956 96 +442 449 462 469 +189 623 209 643 +505 1 525 21 +719 84 739 104 +626 482 646 502 +161 405 181 425 +881 662 901 682 +378 314 398 334 +766 546 786 566 +62 986 82 1000 +160 579 180 599 +15 952 35 972 +411 996 431 1000 +74 706 94 726 +2 190 22 210 +132 395 152 415 +912 428 932 448 +897 203 917 223 +625 868 645 888 +468 963 488 983 +861 322 881 342 +754 192 774 212 +407 447 427 467 +833 372 853 392 +926 953 946 973 +696 288 716 308 +214 174 234 194 +929 859 949 879 +47 621 67 641 +805 506 825 526 +395 232 415 252 +55 371 75 391 +217 553 237 573 +596 647 616 667 +266 341 286 361 +583 827 603 847 +274 566 294 586 +665 452 685 472 +964 360 984 380 +99 822 119 842 +753 896 773 916 +648 15 668 35 +82 429 102 449 +110 517 130 537 +885 276 905 296 +948 367 968 387 +191 670 211 690 +562 56 582 76 +145 698 165 718 +157 587 177 607 +412 832 432 852 +599 257 619 277 +425 817 445 837 +719 497 739 517 +626 16 646 36 +479 842 499 862 +572 217 592 237 +302 398 322 418 +220 386 240 406 +173 405 193 425 +169 576 189 596 +193 63 213 83 +530 558 550 578 +931 696 951 716 +237 711 257 731 +588 175 608 195 +874 372 894 392 +664 58 684 78 +505 544 525 564 +438 762 458 782 +712 488 732 508 +146 14 166 34 +999 828 1000 848 +120 315 140 335 +830 431 850 451 +936 249 956 269 +967 328 987 348 +439 421 459 441 +506 568 526 588 +942 358 962 378 +979 942 999 962 +926 933 946 953 +549 843 569 863 +29 254 49 274 +191 854 211 874 +345 507 365 527 +780 20 800 40 +629 984 649 1000 +356 896 376 916 +118 497 138 517 +706 1000 726 1000 +45 688 65 708 +304 464 324 484 +323 546 343 566 +853 186 873 206 +322 914 342 934 +473 345 493 365 +198 219 218 239 +192 93 212 113 +567 658 587 678 +14 320 34 340 +811 466 831 486 +994 18 1000 38 +61 703 81 723 +527 574 547 594 +402 893 422 913 +284 731 304 751 +626 299 646 319 +44 998 64 1000 +869 894 889 914 +173 302 193 322 +334 722 354 742 +615 962 635 982 +239 467 259 487 +278 14 298 34 +716 388 736 408 +882 607 902 627 +854 241 874 261 +653 452 673 472 +433 380 453 400 +280 882 300 902 +614 851 634 871 +983 250 1000 270 +612 27 632 47 +942 441 962 461 +980 248 1000 268 +413 435 433 455 +452 641 472 661 +141 585 161 605 +221 763 241 783 +778 614 798 634 +218 149 238 169 +851 194 871 214 +708 201 728 221 +652 636 672 656 +543 245 563 265 +214 902 234 922 +511 644 531 664 +369 857 389 877 +197 828 217 848 +505 613 525 633 +720 438 740 458 +959 956 979 976 +334 152 354 172 +405 751 425 771 +704 109 724 129 +533 585 553 605 +673 489 693 509 +440 829 460 849 +705 59 725 79 +443 57 463 77 +270 422 290 442 +405 944 425 964 +577 185 597 205 +575 818 595 838 +314 776 334 796 +387 909 407 929 +730 420 750 440 +347 925 367 945 +349 767 369 787 +256 953 276 973 +330 801 350 821 +808 207 828 227 +599 40 619 60 +584 585 604 605 +564 835 584 855 +851 368 871 388 +906 516 926 536 +661 152 681 172 +33 99 53 119 +236 994 256 1000 +761 255 781 275 +517 323 537 343 +647 767 667 787 +364 959 384 979 +914 270 934 290 +832 29 852 49 +111 734 131 754 +300 511 320 531 +573 962 593 982 +478 417 498 437 +962 417 982 437 +478 412 498 432 +682 942 702 962 +733 249 753 269 +996 719 1000 739 +488 375 508 395 +592 216 612 236 +937 977 957 997 +557 586 577 606 +557 584 577 604 +177 659 197 679 +595 979 615 999 +862 315 882 335 +625 796 645 816 +634 42 654 62 +488 351 508 371 +665 801 685 821 +349 467 369 487 +224 177 244 197 +194 573 214 593 +719 290 739 310 +476 60 496 80 +241 108 261 128 +447 54 467 74 +453 773 473 793 +752 158 772 178 +847 556 867 576 +258 362 278 382 +691 571 711 591 +53 759 73 779 +732 786 752 806 +367 954 387 974 +580 920 600 940 +412 861 432 881 +646 210 666 230 +524 418 544 438 +970 704 990 724 +752 979 772 999 +8 280 28 300 +353 106 373 126 +763 626 783 646 +29 478 49 498 +875 556 895 576 +281 241 301 261 +552 756 572 776 +808 489 828 509 +375 612 395 632 +8 813 28 833 +549 812 569 832 +807 573 827 593 +417 104 437 124 +248 752 268 772 +318 828 338 848 +977 203 997 223 +799 346 819 366 +650 498 670 518 +956 994 976 1000 +98 334 118 354 +452 70 472 90 +580 699 600 719 +463 225 483 245 +169 793 189 813 +888 764 908 784 +726 759 746 779 +253 774 273 794 +797 383 817 403 +560 424 580 444 +52 52 72 72 +228 313 248 333 +612 996 632 1000 +519 13 539 33 +191 956 211 976 +822 63 842 83 +354 397 374 417 +960 548 980 568 +285 804 305 824 +743 976 763 996 +822 940 842 960 +632 324 652 344 +729 974 749 994 +150 701 170 721 +319 392 339 412 +104 852 124 872 +106 895 126 915 +185 614 205 634 +326 177 346 197 +82 508 102 528 +33 169 53 189 +418 601 438 621 +961 97 981 117 +812 168 832 188 +583 308 603 328 +149 101 169 121 +763 39 783 59 +697 624 717 644 +668 387 688 407 +598 856 618 876 +930 352 950 372 +270 643 290 663 +416 53 436 73 +240 605 260 625 +155 936 175 956 +715 12 735 32 +615 925 635 945 +184 81 204 101 +580 2 600 22 +953 662 973 682 +580 609 600 629 +243 953 263 973 +718 605 738 625 +905 391 925 411 +164 212 184 232 +906 184 926 204 +975 192 995 212 +539 269 559 289 +668 209 688 229 +37 499 57 519 +470 828 490 848 +440 632 460 652 +910 914 930 934 +540 405 560 425 +724 164 744 184 +143 26 163 46 +96 781 116 801 +368 124 388 144 +358 160 378 180 +158 862 178 882 +559 248 579 268 +943 298 963 318 +506 207 526 227 +329 569 349 589 +810 405 830 425 +621 38 641 58 +462 156 482 176 +765 928 785 948 +450 976 470 996 +897 282 917 302 +552 904 572 924 +198 400 218 420 +7 23 27 43 +776 58 796 78 +338 443 358 463 +156 460 176 480 +683 333 703 353 +611 707 631 727 +997 291 1000 311 +397 946 417 966 +269 124 289 144 +449 578 469 598 +163 919 183 939 +156 495 176 515 +855 14 875 34 +50 909 70 929 +477 62 497 82 +860 5 880 25 +483 754 503 774 +263 393 283 413 +52 556 72 576 +756 171 776 191 +816 928 836 948 +599 746 619 766 +372 466 392 486 +352 324 372 344 +214 624 234 644 +193 321 213 341 +812 590 832 610 +32 154 52 174 +270 3 290 23 +177 767 197 787 +129 323 149 343 +491 761 511 781 +626 11 646 31 +666 943 686 963 +333 692 353 712 +160 462 180 482 +59 328 79 348 +762 216 782 236 +61 399 81 419 +709 436 729 456 +437 550 457 570 +887 108 907 128 +831 898 851 918 +116 305 136 325 +175 69 195 89 +871 866 891 886 +937 853 957 873 +251 61 271 81 +210 343 230 363 +296 237 316 257 +653 191 673 211 +768 976 788 996 +374 435 394 455 +454 867 474 887 +436 794 456 814 +792 927 812 947 +861 692 881 712 +741 78 761 98 +499 465 519 485 +500 650 520 670 +680 264 700 284 +930 197 950 217 +738 449 758 469 +213 245 233 265 +521 631 541 651 +955 688 975 708 +618 748 638 768 +264 629 284 649 +775 750 795 770 +887 840 907 860 +71 21 91 41 +849 425 869 445 +753 776 773 796 +353 801 373 821 +698 95 718 115 +878 304 898 324 +75 810 95 830 +788 829 808 849 +505 225 525 245 +856 998 876 1000 +996 359 1000 379 +961 352 981 372 +601 646 621 666 +323 553 343 573 +921 71 941 91 +489 616 509 636 +763 876 783 896 +300 938 320 958 +487 617 507 637 +881 852 901 872 +763 878 783 898 +166 329 186 349 +690 425 710 445 +116 836 136 856 +526 113 546 133 +862 95 882 115 +60 155 80 175 +821 463 841 483 +210 293 230 313 +419 880 439 900 +193 983 213 1000 +725 488 745 508 +90 211 110 231 +362 523 382 543 +16 835 36 855 +139 169 159 189 +555 406 575 426 +415 732 435 752 +716 13 736 33 +706 896 726 916 +921 206 941 226 +142 208 162 228 +499 564 519 584 +403 892 423 912 +15 547 35 567 +671 842 691 862 +972 923 992 943 +844 710 864 730 +725 804 745 824 +350 679 370 699 +938 329 958 349 +188 63 208 83 +193 756 213 776 +574 282 594 302 +613 359 633 379 +1000 27 1000 47 +156 949 176 969 +571 842 591 862 +874 546 894 566 +838 466 858 486 +432 262 452 282 +345 181 365 201 +183 688 203 708 +797 402 817 422 +740 667 760 687 +598 592 618 612 +440 178 460 198 +719 855 739 875 +557 116 577 136 +11 406 31 426 +822 994 842 1000 +231 718 251 738 +397 820 417 840 +317 599 337 619 +344 879 364 899 +1000 745 1000 765 +471 38 491 58 +728 460 748 480 +247 126 267 146 +353 56 373 76 +756 135 776 155 +815 678 835 698 +916 949 936 969 +393 356 413 376 +589 574 609 594 +302 506 322 526 +197 326 217 346 +71 554 91 574 +240 859 260 879 +238 386 258 406 +526 62 546 82 +627 684 647 704 +765 137 785 157 +105 998 125 1000 +240 75 260 95 +186 591 206 611 +322 98 342 118 +598 747 618 767 +605 877 625 897 +992 426 1000 446 +466 379 486 399 +88 9 108 29 +39 197 59 217 +121 313 141 333 +722 221 742 241 +541 977 561 997 +277 709 297 729 +677 697 697 717 +845 744 865 764 +646 592 666 612 +729 998 749 1000 +994 222 1000 242 +226 532 246 552 +529 174 549 194 +704 75 724 95 +534 199 554 219 +103 390 123 410 +297 510 317 530 +355 853 375 873 +438 474 458 494 +38 472 58 492 +687 94 707 114 +635 534 655 554 +821 340 841 360 +628 162 648 182 +172 990 192 1000 +150 1 170 21 +853 38 873 58 +437 351 457 371 +992 306 1000 326 +861 813 881 833 +259 741 279 761 +878 826 898 846 +80 740 100 760 +903 900 923 920 +759 543 779 563 +95 603 115 623 +222 195 242 215 +578 505 598 525 +678 737 698 757 +380 201 400 221 +750 193 770 213 +732 686 752 706 +527 595 547 615 +33 391 53 411 +172 293 192 313 +623 736 643 756 +502 644 522 664 +875 239 895 259 +99 938 119 958 +845 345 865 365 +976 857 996 877 +163 303 183 323 +943 430 963 450 +688 61 708 81 +835 141 855 161 +453 381 473 401 +630 231 650 251 +145 675 165 695 +944 861 964 881 +743 299 763 319 +813 506 833 526 +112 66 132 86 +758 793 778 813 +765 268 785 288 +628 542 648 562 +872 756 892 776 +923 750 943 770 +248 798 268 818 +406 368 426 388 +362 450 382 470 +289 294 309 314 +567 795 587 815 +733 584 753 604 +339 349 359 369 +626 987 646 1000 +394 194 414 214 +983 349 1000 369 +295 951 315 971 +461 12 481 32 +386 18 406 38 +588 60 608 80 +665 432 685 452 +596 540 616 560 +9 800 29 820 +917 685 937 705 +316 656 336 676 +803 900 823 920 +453 714 473 734 +311 632 331 652 +152 54 172 74 +504 746 524 766 +339 526 359 546 +428 937 448 957 +448 680 468 700 +596 621 616 641 +533 72 553 92 +61 541 81 561 +171 169 191 189 +850 59 870 79 +628 876 648 896 +593 113 613 133 +922 733 942 753 +549 124 569 144 +619 765 639 785 +972 857 992 877 +755 502 775 522 +876 167 896 187 +615 165 635 185 +73 12 93 32 +966 525 986 545 +630 332 650 352 +226 975 246 995 +819 692 839 712 +212 911 232 931 +283 119 303 139 +234 741 254 761 +937 780 957 800 +223 303 243 323 +709 862 729 882 +831 147 851 167 +923 662 943 682 +890 589 910 609 +363 38 383 58 +554 744 574 764 +14 635 34 655 +402 867 422 887 +946 802 966 822 +793 689 813 709 +987 658 1000 678 +201 682 221 702 +520 286 540 306 +5 34 25 54 +307 443 327 463 +287 281 307 301 +902 524 922 544 +57 226 77 246 +581 837 601 857 +157 122 177 142 +144 986 164 1000 +750 811 770 831 +917 342 937 362 +904 312 924 332 +56 983 76 1000 +680 495 700 515 +718 862 738 882 +487 512 507 532 +83 529 103 549 +113 363 133 383 +432 705 452 725 +95 312 115 332 +555 78 575 98 +528 557 548 577 +170 181 190 201 +631 634 651 654 +788 538 808 558 +396 719 416 739 +999 425 1000 445 +571 723 591 743 +119 119 139 139 +866 667 886 687 +774 370 794 390 +967 165 987 185 +198 977 218 997 +289 146 309 166 +867 739 887 759 +511 129 531 149 +325 677 345 697 +199 428 219 448 +91 435 111 455 +174 918 194 938 +557 740 577 760 +421 335 441 355 +115 505 135 525 +702 134 722 154 +685 874 705 894 +830 563 850 583 +858 602 878 622 +463 94 483 114 +582 696 602 716 +98 493 118 513 +903 359 923 379 +713 744 733 764 +1000 1000 +17 4 998 999 +100 +110 43 160 72 +784 789 822 803 +853 141 889 169 +147 923 166 960 +928 713 975 734 +35 385 60 405 +244 592 276 633 +979 887 1000 926 +100 585 138 597 +404 616 453 663 +655 714 691 751 +126 212 158 243 +984 998 984 998 +920 603 933 643 +373 227 399 269 +482 487 494 501 +323 672 340 687 +252 935 280 952 +744 744 794 762 +414 315 430 354 +319 424 343 465 +158 195 168 206 +912 367 962 382 +660 230 702 273 +534 447 553 492 +319 867 334 903 +35 630 47 680 +301 338 326 360 +403 906 421 935 +930 819 943 830 +43 828 56 846 +323 929 358 939 +549 387 595 423 +945 168 986 209 +134 958 148 968 +740 789 750 809 +422 867 436 887 +242 81 258 106 +488 375 502 398 +396 287 412 319 +342 652 355 673 +718 306 752 350 +618 459 632 471 +924 35 936 47 +328 219 339 262 +893 986 920 1000 +739 48 770 89 +633 195 651 231 +692 726 723 761 +60 621 91 662 +134 569 175 604 +752 534 779 561 +924 29 968 54 +512 436 552 473 +871 609 906 648 +258 591 288 607 +608 500 624 510 +601 873 611 898 +102 361 133 390 +688 390 722 411 +604 604 643 614 +343 611 382 661 +466 306 486 335 +970 101 988 114 +972 115 993 132 +815 637 855 683 +112 745 127 760 +192 359 207 407 +53 998 67 1000 +904 857 933 876 +499 161 541 189 +308 352 340 397 +746 741 784 770 +832 55 865 94 +326 543 344 568 +930 859 951 870 +842 344 877 393 +349 953 397 993 +563 146 580 187 +173 657 206 694 +41 457 79 505 +812 209 849 237 +887 429 935 463 +402 402 413 424 +824 382 850 409 +926 102 953 119 +921 788 952 833 +742 620 759 633 +973 590 1000 627 +983 811 1000 830 +777 383 816 408 +418 71 431 85 +49 434 74 481 +462 326 497 358 +453 288 479 336 +130 113 177 132 +122 778 136 799 +431 190 468 234 +428 110 473 141 +968 632 987 655 +1000 1000 +999 998 2 3 +1000 +817 704 837 726 +560 242 600 284 +918 147 956 170 +875 875 903 914 +770 934 800 956 +694 138 733 162 +201 981 232 1000 +982 358 1000 396 +678 335 717 384 +337 204 376 253 +461 642 499 688 +106 345 155 371 +259 149 305 197 +346 149 369 172 +446 663 470 697 +441 591 473 622 +579 185 624 207 +452 287 494 307 +233 987 275 1000 +582 608 610 633 +213 134 261 178 +622 256 656 276 +433 241 457 273 +641 930 683 959 +104 897 152 937 +567 831 588 881 +11 282 40 329 +707 846 750 888 +91 330 120 378 +919 795 943 835 +800 728 850 775 +302 423 327 447 +600 581 645 626 +578 974 608 1000 +138 697 177 746 +327 501 367 547 +298 513 335 556 +619 722 650 769 +737 66 766 111 +911 270 942 291 +386 673 433 709 +18 635 46 671 +853 868 875 898 +128 634 155 673 +913 735 955 773 +180 385 216 412 +110 672 144 719 +286 897 317 938 +522 665 569 692 +770 361 808 393 +655 135 695 156 +706 355 726 382 +639 770 684 801 +761 602 793 649 +51 545 86 579 +408 948 453 987 +449 428 491 469 +155 994 199 1000 +618 460 657 498 +670 892 701 914 +369 270 398 300 +848 3 889 23 +859 903 905 923 +3 486 23 523 +317 885 354 906 +229 162 265 203 +714 874 741 916 +894 825 933 846 +446 330 482 365 +252 587 294 625 +405 892 454 934 +191 567 211 599 +275 769 307 809 +950 956 994 977 +126 243 170 284 +765 943 814 976 +726 565 764 591 +280 848 313 868 +813 885 836 925 +597 517 635 552 +528 78 550 98 +960 762 1000 785 +223 453 243 477 +107 57 144 93 +159 452 204 497 +129 11 151 42 +899 311 938 347 +284 826 325 855 +271 467 301 499 +267 509 308 546 +3 187 48 234 +29 333 79 355 +413 319 456 348 +214 462 245 489 +694 925 721 972 +865 752 891 794 +341 933 372 967 +522 200 557 226 +603 42 625 90 +812 594 855 630 +931 603 951 629 +259 850 280 900 +305 20 345 47 +918 998 963 1000 +347 882 389 931 +669 152 698 178 +662 36 682 85 +255 25 292 55 +387 733 422 774 +287 900 310 921 +487 390 519 432 +654 894 680 925 +939 836 975 870 +785 485 808 511 +92 310 114 332 +114 575 151 620 +867 829 888 871 +980 980 980 980 +572 369 621 394 +908 144 936 186 +907 136 933 173 +822 541 863 582 +198 867 245 895 +695 395 720 424 +975 754 1000 777 +593 478 636 520 +879 738 904 763 +390 244 418 280 +94 609 134 650 +990 899 1000 933 +47 290 88 338 +15 147 61 197 +549 621 591 660 +984 949 1000 996 +44 642 89 671 +884 863 904 902 +32 302 64 326 +465 969 501 999 +57 411 101 431 +42 756 87 794 +495 167 527 207 +837 79 881 99 +253 615 302 638 +803 848 826 873 +681 910 713 960 +93 139 120 179 +535 936 563 961 +948 451 994 490 +644 475 689 510 +789 275 813 309 +803 845 833 885 +243 985 264 1000 +346 944 386 975 +105 549 134 578 +508 923 534 945 +884 509 923 533 +377 461 411 489 +968 731 996 776 +523 558 561 597 +6 77 41 102 +300 850 329 892 +492 876 512 922 +276 627 308 657 +504 319 535 342 +836 290 868 323 +688 996 730 1000 +600 397 621 434 +758 659 784 693 +81 787 117 814 +528 768 573 805 +445 467 495 515 +490 152 537 197 +164 176 211 199 +285 915 309 936 +555 468 590 513 +600 113 645 156 +239 378 275 417 +148 239 186 265 +953 134 998 181 +503 297 526 328 +331 905 364 928 +541 139 563 162 +369 848 402 893 +791 831 834 867 +787 754 822 801 +454 984 477 1000 +686 398 711 442 +989 431 1000 470 +894 166 932 199 +680 381 721 410 +781 939 829 988 +624 820 674 857 +203 987 234 1000 +158 848 202 891 +759 69 789 110 +118 423 138 471 +507 2 538 36 +162 416 194 466 +852 573 901 615 +667 999 708 1000 +495 672 517 709 +865 473 913 506 +705 775 728 815 +659 758 684 808 +276 367 297 404 +4 757 25 796 +172 147 199 167 +418 527 448 571 +605 217 635 239 +139 559 176 603 +279 786 307 823 +394 16 423 63 +71 130 93 167 +756 885 804 932 +347 727 377 764 +375 318 401 358 +304 117 345 142 +958 876 992 902 +626 889 671 930 +199 968 238 1000 +853 402 891 429 +44 570 85 614 +239 613 263 650 +563 962 605 1000 +742 496 770 516 +625 936 662 974 +363 326 393 371 +876 909 918 958 +252 796 272 818 +470 17 495 40 +337 448 362 477 +8 976 54 1000 +579 109 627 130 +44 971 92 1000 +475 362 509 400 +325 482 353 523 +256 637 280 657 +347 142 396 185 +258 714 292 747 +693 150 721 175 +449 961 492 983 +945 101 970 123 +716 444 739 472 +25 576 48 622 +948 27 998 52 +785 748 827 783 +429 997 460 1000 +844 546 878 587 +630 472 668 506 +984 707 1000 743 +775 337 798 377 +207 915 241 940 +378 873 405 910 +895 96 934 146 +486 965 516 994 +506 138 551 171 +795 183 820 229 +421 618 465 651 +8 803 55 830 +320 741 340 772 +651 283 699 325 +413 464 438 488 +621 883 654 921 +955 726 1000 768 +834 802 878 831 +910 383 943 427 +135 325 160 351 +975 481 1000 529 +311 550 354 585 +462 187 506 209 +828 775 872 822 +529 650 557 670 +389 307 418 350 +951 84 990 121 +225 686 247 707 +390 116 435 156 +403 134 436 184 +685 264 724 298 +764 800 794 832 +914 289 936 329 +862 152 892 196 +417 207 458 235 +542 407 584 431 +283 631 318 664 +108 139 147 182 +541 450 586 490 +63 768 89 792 +253 882 275 905 +631 386 658 431 +497 293 523 327 +260 474 293 507 +704 468 732 515 +138 295 172 326 +506 495 549 531 +948 711 985 734 +834 447 882 493 +677 632 704 658 +724 96 755 146 +875 815 898 860 +328 7 353 32 +686 513 708 558 +576 454 597 486 +698 24 745 63 +5 940 54 975 +650 967 699 1000 +138 174 162 198 +56 433 95 474 +791 259 825 296 +163 923 208 944 +162 446 193 477 +896 708 927 747 +574 82 622 104 +809 122 850 143 +987 523 1000 546 +347 505 375 547 +484 95 504 141 +125 596 159 646 +652 309 695 350 +563 822 583 858 +237 371 272 421 +148 453 183 487 +435 59 466 105 +282 62 329 109 +946 876 978 921 +282 902 319 930 +617 76 652 126 +967 440 993 461 +857 376 905 408 +917 997 958 1000 +275 277 299 313 +501 291 537 315 +87 541 118 589 +485 682 535 719 +143 345 176 394 +340 747 374 783 +815 234 848 283 +617 363 639 407 +34 191 54 217 +647 561 695 591 +986 96 1000 141 +958 734 993 779 +199 131 248 174 +458 432 500 456 +738 684 774 705 +756 245 778 281 +841 308 876 338 +770 727 796 771 +11 54 35 101 +492 68 526 112 +847 423 867 465 +456 778 487 820 +941 781 963 813 +602 511 635 532 +688 12 726 37 +107 937 148 976 +135 449 167 470 +894 155 915 178 +692 105 734 137 +962 515 1000 548 +436 459 470 491 +454 183 491 220 +438 857 471 881 +784 745 812 773 +54 455 103 478 +689 471 722 499 +721 517 768 547 +500 812 550 855 +635 490 656 524 +341 752 373 793 +270 82 316 116 +904 870 951 916 +287 851 331 881 +13 528 53 557 +881 871 912 909 +347 898 375 944 +925 185 959 216 +432 111 461 138 +825 728 863 766 +585 844 631 871 +470 747 494 791 +635 776 662 818 +313 42 349 86 +972 119 1000 150 +270 524 293 545 +503 59 552 79 +949 134 979 165 +781 516 820 562 +657 842 678 885 +816 518 845 568 +440 323 463 366 +274 418 305 462 +945 826 972 856 +933 236 972 272 +500 394 530 421 +431 787 469 813 +439 70 478 110 +732 355 777 396 +909 174 929 196 +171 212 197 232 +256 818 283 862 +120 976 154 1000 +501 55 523 79 +230 27 267 52 +698 178 740 207 +361 431 393 468 +830 226 857 253 +284 321 326 343 +728 122 754 143 +574 301 600 342 +315 205 358 232 +424 387 459 409 +5 901 38 937 +626 441 659 482 +47 387 80 411 +753 989 794 1000 +735 904 778 927 +50 502 73 544 +484 339 525 380 +541 232 570 278 +873 680 906 711 +242 577 281 624 +738 630 788 655 +72 355 93 377 +155 553 188 576 +870 619 914 661 +524 725 545 766 +106 236 152 283 +636 539 674 578 +823 750 860 780 +465 967 500 1000 +149 560 180 608 +373 218 415 256 +595 598 637 623 +668 380 692 403 +379 837 428 858 +842 932 865 981 +655 469 687 499 +461 678 481 713 +146 539 189 577 +228 217 255 242 +320 907 356 953 +427 326 450 360 +517 219 566 241 +601 112 632 141 +465 705 487 726 +163 211 212 248 +813 928 845 951 +842 236 871 279 +910 298 933 331 +724 357 754 406 +518 7 564 47 +50 615 87 659 +645 164 670 195 +571 453 618 487 +600 701 625 728 +247 149 272 169 +449 347 494 382 +200 216 236 266 +110 259 140 290 +853 489 880 537 +827 502 855 551 +545 455 567 496 +969 384 998 421 +22 276 49 323 +619 178 658 203 +652 353 690 376 +188 78 208 120 +156 815 193 859 +184 538 205 576 +770 266 814 288 +523 123 545 159 +602 499 629 542 +573 506 596 555 +207 26 238 68 +519 364 561 409 +555 391 592 436 +266 691 291 713 +845 812 893 840 +888 684 928 704 +793 917 838 949 +723 628 744 662 +862 964 895 1000 +270 693 318 741 +941 11 965 31 +953 569 976 612 +574 452 621 499 +207 449 253 481 +548 677 598 699 +686 339 714 370 +372 595 413 634 +990 316 1000 336 +855 956 894 983 +67 858 95 902 +917 281 937 324 +793 674 828 721 +984 147 1000 172 +597 102 618 139 +644 129 690 152 +835 433 869 478 +972 460 1000 510 +886 584 916 606 +641 378 687 408 +718 477 765 501 +416 606 463 647 +905 226 940 249 +211 166 255 200 +739 731 764 778 +531 594 579 614 +676 972 713 1000 +867 246 892 293 +390 668 435 701 +798 285 846 320 +88 304 114 327 +867 249 909 270 +932 226 962 248 +917 644 953 681 +815 563 835 610 +213 275 236 302 +518 553 539 595 +421 350 453 393 +984 912 1000 943 +807 458 843 500 +990 987 990 987 +372 137 401 168 +570 589 610 630 +841 263 871 310 +351 738 392 761 +398 154 443 204 +942 8 976 58 +963 418 983 448 +877 326 900 363 +229 360 274 384 +42 354 63 383 +141 544 187 568 +101 336 136 375 +624 154 654 196 +724 15 769 36 +271 98 294 143 +929 445 961 490 +871 11 913 58 +505 218 531 244 +422 426 443 447 +585 815 634 853 +664 523 700 559 +825 673 856 708 +196 540 239 563 +26 961 53 990 +776 995 814 1000 +366 208 399 249 +150 250 171 292 +42 288 89 318 +123 279 146 300 +666 20 689 50 +153 583 187 627 +90 534 129 561 +929 288 963 335 +885 794 910 820 +805 863 830 887 +853 982 892 1000 +954 673 1000 718 +981 657 1000 681 +67 26 87 47 +780 535 829 570 +674 527 705 564 +418 812 438 848 +372 728 408 766 +578 956 605 994 +295 811 316 834 +230 587 259 621 +138 264 171 290 +260 364 284 408 +317 747 342 775 +316 315 365 349 +222 137 271 177 +751 439 782 474 +841 632 871 675 +941 915 961 940 +217 644 238 684 +113 680 136 704 +46 553 76 581 +128 188 165 212 +33 765 81 798 +532 67 557 113 +899 266 948 308 +644 45 667 78 +135 386 184 414 +275 526 305 551 +952 229 980 261 +348 883 374 920 +825 787 849 809 +857 113 887 159 +250 842 296 877 +691 6 735 50 +845 511 885 557 +989 794 1000 830 +630 256 676 278 +142 912 163 945 +646 902 683 949 +919 903 953 926 +18 953 43 997 +426 284 463 323 +704 253 745 289 +490 999 515 1000 +810 725 845 769 +604 174 653 218 +707 417 751 446 +644 740 688 769 +962 321 1000 346 +719 316 766 360 +950 1000 984 1000 +467 768 511 801 +299 551 341 597 +559 13 592 50 +305 986 351 1000 +163 228 213 257 +432 804 463 836 +157 55 189 98 +190 176 225 211 +39 82 85 110 +679 212 718 242 +499 338 520 362 +456 648 485 669 +39 979 79 1000 +458 427 480 464 +325 916 353 964 +62 314 95 335 +600 151 637 176 +128 412 164 433 +490 905 534 954 +709 634 747 673 +89 169 131 202 +919 332 964 365 +817 2 839 48 +719 891 750 932 +629 573 651 615 +729 804 755 826 +811 571 848 596 +347 221 394 269 +465 836 488 862 +120 450 165 486 +310 217 346 267 +55 408 86 450 +968 867 1000 904 +465 52 485 96 +155 338 191 383 +793 371 838 418 +179 576 221 604 +948 115 968 145 +318 548 353 589 +550 845 597 871 +545 605 575 633 +27 96 65 130 +645 732 672 769 +499 935 536 970 +227 967 269 988 +595 377 643 409 +13 36 49 73 +435 325 485 355 +21 844 62 886 +253 421 298 466 +678 616 698 649 +2 364 41 389 +725 751 760 777 +772 869 821 905 +480 830 522 855 +991 861 1000 881 +849 138 887 172 +485 25 510 69 +348 780 381 829 +154 900 194 924 +13 884 41 911 +445 899 488 922 +160 463 195 510 +691 445 737 483 +75 517 110 561 +586 171 610 219 +634 293 674 332 +521 34 567 75 +98 783 128 803 +543 890 581 921 +690 773 710 804 +462 339 491 377 +134 66 173 87 +283 524 308 548 +633 869 667 913 +339 208 372 230 +366 249 397 276 +390 913 421 955 +179 331 218 375 +101 181 144 213 +269 484 303 534 +868 380 899 406 +200 681 245 706 +753 690 795 737 +454 707 486 730 +196 978 227 1000 +367 412 387 446 +431 635 454 683 +973 103 1000 148 +546 577 577 605 +583 758 616 786 +588 207 616 232 +63 258 106 306 +63 551 105 571 +915 634 948 683 +916 843 936 885 +92 184 126 213 +907 895 945 930 +435 587 460 633 +889 273 929 302 +994 679 1000 725 +970 335 1000 378 +562 611 600 648 +931 438 977 485 +362 907 388 938 +483 562 503 598 +409 521 456 553 +488 130 532 158 +128 981 175 1000 +128 980 159 1000 +262 18 284 53 +930 410 971 437 +47 346 92 366 +497 819 517 864 +249 537 270 571 +147 593 173 628 +127 158 152 208 +422 57 467 97 +240 642 270 692 +773 608 797 658 +648 418 690 444 +974 142 1000 191 +28 559 54 588 +220 461 267 481 +708 162 757 198 +269 763 295 806 +138 688 170 713 +338 869 368 912 +771 731 809 770 +297 934 322 955 +671 232 710 267 +140 70 174 109 +759 725 797 757 +954 868 995 890 +494 747 535 777 +90 951 126 991 +335 230 381 259 +628 469 664 508 +894 889 938 918 +331 323 362 370 +552 209 601 253 +944 437 979 467 +766 760 793 786 +201 10 226 42 +944 533 968 572 +372 27 413 71 +397 456 435 505 +27 349 56 385 +731 886 764 918 +850 753 882 787 +983 170 1000 196 +176 653 212 684 +517 846 556 889 +374 543 421 577 +660 5 707 50 +639 407 675 434 +103 124 133 151 +376 704 426 726 +883 570 920 602 +902 410 923 457 +268 685 295 711 +432 481 475 510 +770 591 799 632 +390 292 438 318 +511 180 536 216 +518 174 540 210 +751 216 780 250 +502 62 548 110 +802 720 842 762 +994 296 1000 336 +152 912 185 947 +236 595 265 618 +240 986 289 1000 +429 717 456 738 +89 161 130 200 +116 110 156 158 +301 474 334 508 +856 156 889 198 +506 338 548 361 +860 129 893 168 +143 562 176 591 +918 972 948 1000 +494 971 544 1000 +639 21 677 54 +216 341 244 374 +188 294 231 319 +996 271 1000 307 +56 205 104 225 +121 483 171 525 +593 636 628 667 +340 725 375 754 +300 180 345 203 +729 603 774 632 +420 442 467 484 +39 198 89 236 +241 508 277 536 +641 89 679 118 +522 281 551 312 +691 566 741 596 +49 611 69 641 +943 26 978 74 +123 882 152 909 +718 16 748 65 +999 476 1000 497 +695 936 730 963 +296 188 341 210 +893 991 917 1000 +476 213 513 236 +59 852 100 892 +526 208 550 250 +227 648 253 696 +315 169 338 193 +324 542 373 564 +826 32 849 68 +274 135 294 157 +122 64 145 93 +793 328 838 350 +506 903 551 952 +519 575 543 609 +235 810 266 833 +153 523 195 547 +489 649 524 696 +954 701 986 740 +815 544 860 590 +440 306 472 354 +184 432 208 463 +56 308 90 355 +337 492 365 524 +223 167 267 217 +825 662 873 710 +546 742 591 770 +750 210 792 256 +586 524 634 544 +498 581 543 606 +629 65 667 90 +200 96 239 133 +55 747 95 784 +5 368 49 402 +663 253 713 288 +264 758 307 798 +927 932 954 970 +914 874 945 918 +625 616 663 648 +235 665 265 699 +70 437 94 485 +971 352 993 390 +389 412 425 447 +939 61 975 99 +885 764 912 810 +506 522 548 569 +857 582 890 618 +573 695 619 743 +563 163 599 190 +738 649 772 680 +298 782 327 830 +940 649 977 684 +614 547 635 574 +713 852 760 879 +292 675 340 720 +640 798 676 830 +516 847 542 893 +434 747 454 769 +736 466 772 489 +469 336 499 377 +168 629 216 659 +348 934 397 968 +46 544 83 568 +148 10 187 43 +753 800 791 833 +935 732 982 759 +941 904 965 937 +18 30 63 51 +184 642 229 666 +260 554 285 590 +128 901 168 942 +38 737 82 784 +764 238 796 270 +389 182 426 218 +476 70 517 101 +290 362 332 392 +636 507 660 548 +339 790 381 836 +673 830 711 862 +548 580 589 620 +968 594 1000 614 +750 268 773 299 +504 49 554 87 +117 555 143 576 +260 737 286 772 +799 962 822 985 +853 994 879 1000 +686 854 735 894 +572 39 607 68 +342 760 376 804 +804 869 845 893 +942 759 975 807 +145 641 176 690 +756 58 794 86 +406 552 429 575 +274 545 311 591 +956 7 1000 41 +670 322 707 358 +533 751 558 782 +853 467 902 512 +102 540 133 565 +954 686 997 736 +229 110 269 146 +406 364 441 386 +963 593 996 622 +155 703 204 748 +229 117 264 144 +156 977 202 1000 +667 983 702 1000 +195 717 223 767 +281 63 301 96 +399 508 449 529 +252 765 280 788 +515 697 557 731 +516 684 561 712 +97 329 137 366 +449 261 494 306 +644 754 680 776 +438 425 473 458 +475 873 511 905 +725 101 771 146 +238 361 287 409 +726 638 759 659 +906 284 926 316 +973 41 993 66 +828 49 873 90 +536 481 582 522 +161 527 195 552 +901 492 940 528 +144 225 181 262 +24 800 58 837 +100 350 136 373 +986 642 1000 678 +305 923 342 970 +398 672 438 704 +811 125 848 156 +627 830 663 868 +230 543 276 573 +393 735 437 780 +908 192 941 215 +302 593 351 628 +951 672 990 721 +771 500 799 540 +814 655 855 695 +554 364 582 396 +30 845 74 867 +198 782 245 818 +961 48 1000 82 +302 40 340 77 +525 129 557 151 +373 78 407 118 +132 753 173 785 +294 299 341 326 +839 241 883 272 +581 204 623 236 +754 553 800 600 +598 840 623 869 +203 307 238 332 +512 587 545 637 +491 752 533 779 +135 551 184 574 +2 670 33 707 +606 732 636 772 +361 854 401 897 +853 763 887 795 +770 1000 805 1000 +509 772 537 800 +356 870 395 913 +692 374 740 402 +700 438 739 471 +96 570 130 620 +136 676 162 712 +82 198 119 241 +863 3 892 29 +717 181 744 221 +501 326 547 348 +330 721 373 764 +656 860 690 885 +770 665 790 704 +932 687 977 715 +387 369 431 412 +270 237 313 286 +397 205 442 225 +239 921 263 955 +558 373 585 395 +396 840 425 886 +1000 1000 +999 998 2 3 +1000 +753 709 777 737 +847 213 869 243 +111 968 141 990 +332 587 362 613 +161 147 186 175 +98 53 121 82 +600 296 626 320 +60 207 88 234 +982 215 1000 242 +578 432 599 456 +870 75 892 97 +637 626 665 656 +222 717 243 739 +255 177 279 197 +731 62 753 85 +694 452 717 475 +403 658 423 687 +892 844 918 869 +511 597 540 624 +314 473 341 495 +55 405 80 434 +619 488 646 517 +253 650 278 680 +370 196 396 220 +951 90 974 119 +467 857 488 883 +672 360 692 382 +589 663 613 692 +427 836 454 861 +644 394 672 416 +294 978 320 1000 +188 940 209 970 +290 701 318 723 +677 253 697 273 +199 93 219 121 +895 456 924 478 +979 686 1000 715 +497 691 524 717 +489 460 514 486 +126 405 152 435 +113 666 140 690 +364 436 384 461 +779 823 803 849 +248 212 272 232 +104 972 129 1000 +966 945 989 971 +912 249 940 270 +447 789 472 819 +477 912 507 934 +439 994 469 1000 +771 403 791 429 +521 53 547 80 +426 243 452 264 +760 877 789 907 +636 164 658 188 +859 766 880 792 +362 449 388 478 +365 993 394 1000 +829 959 855 987 +905 478 933 508 +859 531 888 552 +53 101 79 123 +912 147 933 172 +111 511 137 538 +394 529 424 554 +68 471 96 496 +533 152 556 182 +268 32 291 56 +698 130 722 159 +555 134 576 159 +942 830 963 858 +590 698 618 725 +230 539 256 561 +151 464 175 491 +73 140 96 160 +772 836 797 860 +754 193 776 217 +584 21 609 43 +796 159 821 188 +894 184 916 206 +507 809 535 836 +657 559 682 579 +861 740 887 770 +500 506 524 532 +100 223 130 252 +392 483 412 505 +815 197 836 223 +231 801 256 829 +873 172 897 197 +11 44 34 66 +120 390 149 413 +989 25 1000 47 +516 805 538 831 +827 645 848 672 +289 105 315 135 +730 15 756 43 +398 289 418 309 +509 697 539 727 +631 847 657 867 +14 701 39 731 +566 397 587 420 +487 566 516 588 +659 483 680 507 +717 529 743 554 +93 889 118 919 +987 988 987 988 +667 126 695 147 +40 389 65 410 +179 825 205 855 +54 506 76 530 +574 798 594 819 +735 669 762 695 +585 574 610 603 +758 925 778 945 +393 709 419 731 +430 221 456 241 +892 749 919 772 +99 614 123 641 +141 140 163 165 +535 366 565 388 +458 243 483 269 +381 630 401 654 +111 53 132 80 +654 897 675 917 +154 967 179 990 +981 84 1000 109 +767 95 789 124 +886 650 908 678 +696 377 725 398 +423 744 443 773 +799 89 827 110 +771 57 793 87 +401 27 423 56 +849 441 870 464 +663 329 688 350 +895 56 920 82 +470 671 493 695 +263 409 288 435 +682 851 711 877 +489 263 518 292 +415 272 441 296 +907 911 934 931 +860 329 880 353 +499 178 521 206 +798 583 824 609 +398 26 427 47 +145 440 174 468 +982 800 1000 823 +780 526 801 548 +239 510 262 538 +423 84 451 105 +71 441 101 471 +331 605 359 633 +900 442 929 463 +113 871 139 899 +30 447 55 477 +741 600 770 622 +942 517 967 537 +165 742 186 762 +353 863 378 891 +432 74 458 103 +767 705 793 731 +833 423 861 448 +489 703 513 730 +269 865 289 892 +721 24 750 51 +60 819 80 846 +580 175 600 195 +100 866 123 886 +646 400 667 428 +952 204 978 224 +910 757 938 779 +134 849 164 870 +118 711 138 731 +296 922 317 951 +314 683 339 706 +829 369 849 389 +764 630 789 654 +881 636 909 657 +724 969 752 997 +213 346 236 373 +911 177 933 198 +721 245 742 266 +919 969 948 997 +834 568 862 596 +302 516 331 546 +888 154 918 176 +863 94 891 123 +470 805 498 831 +442 321 470 350 +650 148 679 178 +211 511 234 534 +24 975 44 1000 +443 129 469 151 +372 703 396 727 +46 177 75 199 +708 759 737 786 +118 452 146 472 +971 656 1000 683 +48 112 78 141 +470 451 494 472 +481 707 501 734 +393 539 413 562 +220 289 250 317 +716 34 744 54 +126 926 152 948 +875 214 899 236 +380 953 402 982 +713 927 736 947 +746 900 768 925 +655 775 675 805 +852 994 880 1000 +924 261 945 285 +247 560 271 583 +681 17 711 40 +234 173 257 194 +660 965 684 990 +545 78 573 106 +700 338 728 367 +486 693 509 720 +4 193 28 219 +391 342 413 366 +893 820 914 840 +761 247 788 271 +302 74 325 103 +759 106 781 126 +90 774 111 797 +329 334 350 356 +906 85 934 115 +642 362 666 387 +842 583 862 603 +23 598 50 623 +228 712 254 734 +951 581 981 609 +307 690 337 716 +917 293 940 313 +515 384 539 406 +193 306 214 336 +880 429 905 455 +906 208 930 234 +587 811 611 832 +661 249 683 275 +18 797 46 820 +309 499 330 524 +756 467 784 493 +890 824 911 853 +318 660 343 689 +261 211 282 236 +642 383 662 405 +209 412 235 441 +23 80 49 100 +515 821 537 841 +780 571 802 597 +872 410 897 438 +516 995 544 1000 +636 317 656 338 +45 955 74 983 +646 733 676 763 +732 795 753 816 +541 858 567 880 +914 412 942 433 +300 345 325 372 +662 259 685 284 +215 626 245 654 +930 637 956 662 +866 636 891 665 +936 71 960 100 +476 888 501 908 +202 920 228 940 +718 13 742 43 +494 196 520 224 +235 753 258 773 +765 705 786 725 +898 815 922 844 +381 600 411 627 +458 828 488 853 +803 415 825 441 +693 793 723 818 +261 265 291 295 +470 62 499 91 +526 99 555 128 +143 162 169 184 +790 430 820 457 +13 635 34 656 +199 168 221 189 +351 842 381 871 +568 710 594 731 +757 462 777 491 +215 455 235 476 +391 184 421 204 +813 39 833 60 +609 317 633 338 +261 986 288 1000 +542 877 571 906 +524 339 552 363 +99 364 121 391 +222 461 242 482 +378 574 402 599 +555 920 581 945 +764 679 794 705 +771 366 800 386 +847 992 871 1000 +786 672 810 702 +255 169 276 199 +359 60 380 90 +468 742 496 769 +455 869 481 892 +467 496 487 525 +909 684 937 707 +719 602 743 624 +807 892 834 912 +321 11 345 41 +993 282 1000 312 +217 828 243 852 +777 485 805 512 +230 188 258 213 +496 184 522 205 +20 755 44 782 +19 727 40 749 +785 227 806 249 +548 910 568 936 +950 546 974 566 +533 522 559 542 +404 345 425 365 +495 634 515 656 +149 444 172 471 +3 626 29 646 +554 139 580 167 +986 816 1000 840 +722 567 752 593 +100 429 130 451 +358 203 382 232 +429 551 453 571 +974 687 1000 716 +603 969 632 996 +88 476 113 497 +930 651 959 677 +669 949 694 977 +312 985 337 1000 +913 411 937 433 +96 228 125 252 +678 535 700 560 +733 296 760 319 +758 401 783 430 +181 484 203 514 +209 930 235 957 +603 407 623 437 +203 185 231 213 +619 747 648 773 +365 337 388 357 +605 550 635 577 +82 425 111 455 +954 793 981 823 +509 984 539 1000 +232 686 261 715 +602 321 628 345 +168 908 190 930 +206 920 236 947 +446 911 475 935 +796 665 826 688 +283 185 307 211 +718 234 743 256 +117 349 146 374 +911 811 933 837 +482 566 512 594 +533 918 557 941 +906 429 929 459 +979 833 1000 856 +557 700 585 720 +163 621 183 642 +156 517 180 546 +32 433 58 462 +343 238 363 259 +853 110 881 139 +778 709 807 730 +769 744 796 770 +963 370 989 399 +129 231 153 256 +159 131 186 161 +826 697 853 725 +466 993 493 1000 +344 800 364 822 +709 567 732 597 +451 454 476 477 +25 770 53 790 +239 36 267 66 +48 988 71 1000 +534 768 556 789 +120 646 140 673 +817 607 837 627 +73 925 96 949 +586 763 611 784 +986 666 1000 687 +198 815 225 838 +47 497 71 523 +574 442 600 469 +710 585 734 605 +8 26 30 46 +337 273 361 297 +589 68 615 95 +430 785 459 812 +772 513 794 539 +79 874 103 899 +882 768 907 796 +504 195 527 215 +866 296 893 320 +95 621 122 642 +415 925 443 952 +137 237 163 266 +135 538 157 568 +879 682 903 702 +788 38 813 62 +369 412 393 442 +757 189 783 215 +359 289 380 309 +608 331 628 357 +782 852 805 882 +98 363 122 389 +87 53 111 78 +955 634 975 654 +990 508 1000 536 +89 484 110 508 +357 25 377 53 +359 831 388 855 +78 56 103 81 +529 184 551 212 +717 823 739 850 +993 883 1000 903 +724 808 754 834 +832 986 857 1000 +448 856 478 883 +835 912 859 940 +36 405 59 433 +858 986 879 1000 +563 140 589 169 +494 229 523 252 +341 252 369 275 +607 107 637 134 +253 987 279 1000 +377 693 402 722 +56 864 79 894 +649 397 678 425 +638 785 668 814 +715 630 738 655 +472 912 494 936 +460 628 488 652 +607 857 636 879 +923 281 949 310 +422 464 444 492 +919 204 949 224 +514 88 544 116 +938 27 960 53 +39 241 69 267 +597 241 626 268 +598 299 622 328 +618 42 644 67 +577 389 606 416 +762 623 792 650 +684 686 711 711 +245 480 266 505 +228 340 250 370 +478 333 499 358 +417 159 437 186 +490 68 518 92 +380 864 407 885 +260 326 287 350 +330 749 360 775 +173 240 203 266 +81 230 104 259 +123 529 147 555 +378 183 401 210 +667 292 696 315 +906 392 930 412 +29 970 59 1000 +27 586 52 609 +208 1000 238 1000 +171 6 199 32 +86 474 113 504 +590 789 614 818 +513 267 538 294 +441 202 465 231 +512 312 536 332 +780 21 808 45 +661 651 689 671 +450 920 471 949 +708 254 728 281 +900 118 928 144 +717 912 737 932 +383 222 404 251 +350 505 378 535 +934 240 961 266 +849 884 878 910 +279 880 305 907 +411 321 433 342 +195 739 219 766 +562 18 592 40 +632 221 654 250 +22 442 48 464 +524 932 550 962 +477 306 497 334 +376 892 403 918 +559 657 587 677 +204 266 233 289 +938 73 967 98 +649 987 670 1000 +635 815 664 839 +993 63 1000 90 +444 17 473 39 +233 520 253 543 +788 343 808 365 +916 543 941 566 +428 175 450 203 +616 374 642 402 +662 990 692 1000 +719 119 741 144 +848 900 871 922 +810 765 836 785 +70 84 91 108 +253 419 277 447 +635 211 659 232 +734 29 764 54 +428 419 458 442 +104 317 126 344 +275 110 296 131 +959 61 988 84 +613 624 638 644 +774 821 804 851 +106 491 135 516 +550 609 573 629 +826 188 856 217 +197 456 218 479 +855 15 883 37 +455 289 484 314 +969 513 998 536 +771 907 800 929 +506 635 535 664 +202 12 230 38 +201 167 228 194 +742 269 767 293 +756 630 781 651 +581 596 610 621 +749 71 773 96 +888 359 917 385 +592 651 613 680 +589 249 610 279 +135 476 157 498 +939 535 962 559 +255 979 284 1000 +20 364 49 386 +210 237 231 264 +664 620 684 648 +543 845 565 875 +366 564 388 593 +128 814 149 844 +585 458 613 482 +103 170 123 196 +638 936 664 965 +333 225 359 255 +584 129 607 153 +246 87 270 117 +234 820 264 847 +572 702 598 726 +278 107 304 128 +137 289 165 310 +555 898 577 928 +914 689 937 709 +621 751 647 772 +730 695 760 719 +212 161 241 188 +379 538 407 563 +861 640 885 664 +487 827 507 850 +543 599 565 620 +695 558 725 578 +568 867 589 891 +230 334 255 354 +980 899 1000 922 +523 372 543 400 +521 773 549 793 +401 36 422 64 +432 27 454 57 +292 426 316 451 +515 247 536 273 +256 961 281 983 +587 662 610 689 +838 288 859 309 +976 527 998 549 +323 432 348 462 +842 709 862 735 +763 963 790 991 +379 97 409 123 +265 771 290 794 +395 619 423 642 +795 451 816 476 +929 259 953 284 +779 712 802 741 +284 359 311 386 +140 394 168 421 +190 583 219 605 +320 941 348 969 +716 353 740 373 +494 316 514 340 +445 771 471 797 +691 620 719 645 +126 70 153 93 +674 655 696 684 +859 322 880 343 +706 270 732 290 +178 635 199 659 +113 948 141 974 +309 126 333 155 +354 534 382 557 +992 793 1000 816 +642 10 670 36 +103 515 123 540 +355 131 383 161 +646 589 675 619 +856 741 876 770 +281 391 307 413 +655 722 682 746 +384 855 412 876 +276 607 304 631 +74 713 98 736 +740 38 761 60 +247 19 274 41 +762 489 787 511 +124 173 150 195 +157 523 183 552 +454 861 474 885 +688 225 709 249 +963 986 992 1000 +398 98 428 126 +422 83 443 105 +929 383 954 413 +937 702 964 725 +366 705 388 725 +728 306 758 332 +60 647 82 670 +309 924 336 944 +233 318 260 345 +240 952 263 973 +329 856 352 881 +450 670 472 699 +903 194 923 218 +572 49 601 70 +945 827 968 855 +94 361 120 386 +69 18 99 40 +832 453 860 476 +218 812 242 842 +600 2 625 28 +293 991 318 1000 +584 846 610 872 +984 106 1000 127 +106 547 132 570 +868 727 891 754 +391 637 421 666 +825 425 847 450 +728 16 749 41 +56 395 79 419 +309 291 339 312 +948 371 974 401 +333 90 363 118 +937 102 964 132 +862 450 888 478 +601 920 629 941 +703 122 727 147 +912 628 942 656 +419 5 449 26 +399 272 423 292 +667 923 693 952 +621 319 650 340 +554 634 581 654 +92 489 112 512 +543 806 565 836 +63 600 92 621 +461 68 486 95 +819 523 849 547 +915 257 940 278 +890 977 912 1000 +701 444 731 464 +790 6 811 32 +69 887 92 912 +686 217 706 242 +693 606 713 628 +13 907 39 936 +233 389 258 415 +260 228 289 256 +323 353 351 382 +350 613 379 635 +538 195 559 223 +98 472 120 499 +974 691 996 712 +471 420 497 442 +473 103 496 123 +165 750 195 780 +480 991 505 1000 +182 693 204 719 +508 50 534 76 +363 614 389 634 +574 420 601 444 +196 167 217 195 +438 331 463 353 +3 769 31 795 +507 642 532 667 +241 661 270 681 +127 37 148 63 +311 832 334 854 +821 498 851 521 +190 562 213 584 +71 902 92 930 +897 788 923 813 +798 154 822 184 +551 278 573 302 +753 54 776 82 +179 335 199 365 +979 633 1000 663 +493 466 516 491 +250 707 275 735 +70 904 95 926 +214 972 242 994 +2 781 29 804 +474 20 499 40 +969 224 989 250 +292 460 317 486 +901 448 926 475 +164 607 191 637 +791 481 816 508 +606 274 629 294 +994 68 1000 97 +569 25 599 49 +277 476 307 499 +754 242 775 267 +405 556 433 583 +840 562 867 589 +620 255 642 284 +994 66 1000 87 +431 207 455 237 +394 874 424 895 +814 963 838 992 +702 235 724 258 +881 269 905 298 +915 980 942 1000 +315 33 339 60 +309 714 329 740 +277 599 301 626 +277 219 302 244 +168 776 197 806 +6 503 29 525 +698 325 726 348 +706 535 734 563 +623 625 652 648 +570 453 590 480 +851 505 875 535 +550 741 578 765 +545 595 573 623 +923 98 953 124 +245 258 273 288 +218 799 246 823 +727 793 755 819 +348 240 371 270 +74 909 100 938 +178 461 198 484 +694 196 716 225 +405 20 428 48 +787 419 816 444 +745 164 774 190 +412 257 442 286 +974 366 995 395 +248 387 278 415 +815 33 841 56 +180 767 202 792 +341 169 367 194 +269 760 292 782 +836 703 856 730 +198 656 223 686 +404 420 426 445 +848 705 870 725 +382 47 412 76 +823 430 846 459 +385 559 409 580 +899 906 926 935 +663 688 686 717 +157 309 186 337 +534 531 562 558 +245 335 267 356 +678 434 702 463 +43 928 64 958 +442 780 462 806 +465 830 491 856 +251 85 280 110 +487 686 515 716 +874 313 902 336 +640 170 666 197 +354 190 384 212 +847 527 867 549 +607 932 628 955 +972 991 996 1000 +397 673 421 696 +855 507 875 529 +771 162 801 190 +818 249 841 269 +849 679 870 706 +617 96 639 116 +772 718 798 744 +265 90 290 118 +363 787 387 809 +923 970 944 997 +570 775 594 795 +411 81 431 111 +471 973 495 995 +489 339 510 369 +227 72 251 93 +261 590 287 610 +120 203 143 230 +275 674 299 694 +751 180 781 209 +735 839 756 859 +52 755 73 777 +575 870 600 899 +230 527 260 556 +538 257 564 284 +425 78 452 102 +548 158 574 183 +362 643 384 668 +302 940 323 969 +763 359 786 380 +955 349 978 371 +368 570 390 598 +963 655 984 684 +587 39 612 61 +18 803 42 829 +912 238 938 262 +957 792 982 821 +97 246 120 269 +516 403 536 426 +844 598 872 620 +477 27 505 49 +687 920 717 940 +971 813 994 834 +84 86 114 106 +105 272 135 301 +107 691 136 714 +894 271 924 299 +108 678 133 703 +733 280 758 308 +601 306 631 335 +939 752 966 775 +656 909 676 937 +192 807 216 835 +757 27 785 55 +534 192 564 215 +175 536 196 561 +146 413 171 439 +997 18 1000 40 +244 756 269 776 +991 281 1000 309 +243 356 272 377 +903 142 931 169 +132 560 162 582 +880 875 904 901 +868 491 889 519 +923 257 945 277 +518 722 539 750 +755 162 775 192 +64 578 93 598 +736 342 756 364 +360 883 381 904 +351 19 371 49 +851 265 874 295 +159 229 183 251 +241 617 262 645 +5 361 31 384 +264 751 290 773 +970 606 999 632 +471 656 501 685 +274 841 299 870 +835 185 862 205 +24 162 44 188 +255 144 277 168 +142 4 164 26 +108 11 138 35 +676 10 698 33 +619 497 646 520 +998 928 1000 958 +990 115 1000 138 +978 115 1000 145 +244 546 269 572 +154 16 174 40 +385 958 410 979 +921 94 948 116 +688 952 715 979 +713 313 737 339 +185 375 214 400 +858 571 888 595 +581 401 611 421 +433 64 463 92 +822 325 852 351 +921 321 946 342 +650 862 675 886 +130 303 151 332 +492 301 514 321 +846 905 875 925 +820 589 846 611 +280 985 310 1000 +194 494 214 521 +194 821 223 844 +727 135 748 155 +669 717 694 745 +259 100 287 129 +149 509 170 538 +104 991 124 1000 +463 368 484 394 +806 737 826 764 +232 883 256 908 +983 638 1000 663 +396 427 424 447 +638 194 661 220 +312 433 335 455 +355 581 378 608 +831 589 855 619 +735 742 756 771 +525 16 555 41 +164 37 191 62 +437 6 464 29 +598 213 619 236 +784 619 810 643 +873 586 894 609 +603 43 623 65 +659 956 686 976 +81 692 111 721 +424 992 451 1000 +598 528 624 549 +424 588 446 615 +703 446 725 474 +897 290 917 319 +612 736 634 761 +218 974 245 994 +263 739 287 764 +722 329 751 355 +166 943 190 968 +41 509 65 533 +381 997 404 1000 +15 70 42 94 +489 111 519 136 +723 92 743 113 +555 190 581 215 +741 990 764 1000 +432 574 457 597 +838 376 859 404 +451 833 478 856 +338 16 361 41 +611 397 634 423 +926 614 949 637 +605 607 628 635 +12 602 37 627 +121 192 142 215 +618 610 641 636 +434 578 456 601 +683 52 705 82 +879 628 906 652 +941 310 969 340 +605 750 627 780 +724 102 746 125 +495 943 522 963 +550 690 580 715 +188 360 215 386 +268 178 291 198 +276 855 301 882 +63 98 91 127 +75 18 95 47 +363 801 385 826 +95 643 123 670 +846 182 868 202 +579 265 607 293 +371 628 391 656 +30 405 58 433 +23 92 45 117 +496 498 524 528 +91 298 111 318 +274 431 303 452 +707 576 727 600 +818 308 846 335 +955 660 981 690 +272 62 300 82 +685 577 710 605 +90 545 117 565 +204 216 226 246 +189 699 217 723 +279 258 309 288 +70 767 99 789 +476 280 496 307 +504 472 524 499 +471 329 491 354 +82 660 109 690 +957 933 985 962 +832 601 854 629 +391 155 419 185 +13 470 34 499 +476 240 499 263 +0 0 diff --git a/ra-preguicosa/output/1 b/ra-preguicosa/output/1 new file mode 100644 index 0000000..091cc36 --- /dev/null +++ b/ra-preguicosa/output/1 @@ -0,0 +1,45 @@ +0 +impossible +14 +impossible +12 +14 +17 +30 +impossible +27 +12 +54 +57 +48 +55 +56 +147 +222 +208 +207 +239 +impossible +242 +230 +134 +226 +34 +218 +99 +impossible +97 +102 +impossible +102 +2493 +165338 +810 +impossible +662674 +2997 +impossible +3179 +3016 +impossible +3296 diff --git a/ra-preguicosa/problem.json b/ra-preguicosa/problem.json index 8f2f975..2da5032 100644 --- a/ra-preguicosa/problem.json +++ b/ra-preguicosa/problem.json @@ -39,10 +39,10 @@ "cpu_count": 1, "build_pdf": true, "pdf_format": "ds", - "io_samples": 3 + "io_samples": 0 }, "solutions": { - "main-ac": "", + "main-ac": "ac.cpp", "alternative-ac": [], "wrong-answer": [], "time-limit": [], diff --git a/ra-preguicosa/ra-preguicosa.pdf b/ra-preguicosa/ra-preguicosa.pdf new file mode 100644 index 0000000000000000000000000000000000000000..23317df0835611bd61c6b469d1867a81107933bb GIT binary patch literal 29320 zcmbTeWn9#4^FF+=EZyDRxj`e{ogyIJEhPvdyEM`zB}kVFf*^v5bV-+h2@+BwQX;j_ z;^lS6<^G==fBWGDFTXSAoO2#?%rV1dprR%O5f;Pe8k_2w#TR1*vtF}z$G>z5Uqr{r z+avflEI<5k zw$`JxGbG~*|K8-$+k?RUu;)iFC+6ucJuYQ`qFb;TGd*+7d?MmZe832JA3or&f$w2- zl{WQw$!_22j;7D)%X}Z3!wJX#t==Y?fr|S6b^W*O<$RlM-E0bX0HO(g@Y&v(}=zO|KYaEAB_l#zi zzcegB{;Ro$5nmzd>q>Lyh91_izb9wQ|I|~ z{F`4i-4r$bZYyK8jw4SLKK`1kC}LSjS}cEL6FcaT2Z3aNkh$@FP=T3#uYDxXQa8tg zbnfdr&I3F1YmIr~A{GNR1e4$!Yq)Zo*{uw%lGj_`0_V8f8-@t5siScPb4cr+q`$?Y zcV$!2;$1WmblD*UV44``2nJgsh6ovDuZpPke@`3bnvIX>=`t1mw4w2Bogvwql1~tp zaJf+p5n@=-BdWqONO?;qXo;H!il<(Yu>KB zW5hcpY9d9}L1v=g-*MMocTt<5e($p>tC#zNkBcJC7+PGBzmz39<=`BD3cV))!R3X; zunC2QhIwqb$YbujI}vk!-DBp2D1M`R?WTeSVqC#zC_3u}!H9t(~=Y zPV9kaUe{h_iaB?5*HiZ`|EVvQEb}*Y#bSjI{p^WviMwj0zjq^?H>D*ZpThoejpSx7 zhwR4H`WN_2VVzjgqIV?Ic8{!27&#a z=cFY6%5to%|2xmYpi?k$Q?LOTXs>Jxa^Q%jRIXJLCSaWbbOUemeD;$H_FIb;F!Ncv z2>`Y1$=;&Uiq|r3*(<=zry^|Gv!W~^q9U|!xnxD@xqb#zEFc2XBX0Y*g!qB{FaRI= z7}?N#u_&4^7X6bio`xBtKG*~-Y6ylJfg4RUAWQs9P^bYw(Kt@UPdGb+Cp)Y;A`K(^ zWo!gr_RGpgN}7gl{Mj#!5e*S+*)J268jB+o1+yy?I*~}0RI=;`JXct008ivu$Wf&Tj3|LtF|k$U`2Fe&yt0VrDe%lhk^m~TrI^YJft5J%_{vr|qP8jR1$S+JC+ zjMYcdiuk(n6XCH0wWQkUsr#v6B>m9P^i!%Ny~e9t3$$8KSOhI%oiYuOo>B#k>%ZP> zmLFa1yDQ}zq~D{E-@j zJcSmOu21efbz7mA9l8@0|NTTE5`Q1*|Mn3~Yyt*7KT>RaV^-*|`oB;smk5mmQusIGV5{ZmeQ|h*JPrY8RsL4!dgt>`rSq36EN2r7Wj)`@k zk(vi2^FD_F;tZUA&R-FN2)W^bCPE~Bw;n2b@dzm&gSdAokb=fUEOD_ZY!v2O6xas_ z?vvv(GL&?tn(!&z=X8q4dQPFCzH1nYb%#H3IoEuy*R7%Mg;SQ(4|(k^XF8sf_NTBw zy5~2~bk<@m`MaVDb|qLoii+@sIb|E2a5}^fQayr8*ieoZvY1y8gk?y4H4&zzWddUx z?CEmuoeEEwk1e;Csaj)93V9zWyl15(_G?vV<(c!tj2gkcTHNUv#5ObI!cGZHG89;B zYhSh7Kqhh;%Z}xb&Bi7|F4 zVkJOGJEWLnV8lBGjRz%v_aFp(aSy_vGcXAwumQjU1~OLuD}!-3uzmz|gETq+PGPik z{-_+L`i~rj2&IX3RR%?x3G35Dqk=+_bPYJuukn^ZF9TPJGiyMQ*enq}GCO$oH4!yEtx_?XlrIx)es>Gz`Jy}Gj<5Wb>cs~`+`Kd(#lyM0jb@Ag5V5*N;VHL0@1 z5elSgu?DF+U1T`~yd|~0YUFToKApzLU{iOu;&D^SJoRt5nba!z=7IK`Tv6&T=L!mL zIZrVkR4Lzbzdk_Nzqgt?Pp8{y7n|tDe@vkVO_XpXPo!aV$QN1*X<>rgdsxxEme};d zC3Y?m5P`omuz>?_<>#gApx`7TpoJMBssPRY?H>GB53B)Ue2-3~eT4T7wwn@yjXC?N z+}MZ+V&8o#PL*O;_4;-~(zyRMm?(f#rbwwW>%mkAhwtKLd>hIaQ&GDmS@|&U4EQbS z=Ofo0m_O6ieghI^`#wVBGRW^PgNR?;W&e=~DG2@*$`lm;2<4od^XK?~g)-8?7Lbl4 zK@5-(qLSh)5{x=~+d~}gjgGQgz_?6#05=OlBg}CJNXD5SQYD2$%00v3>4@xT#|^}b z^8_To2mu2pBr0b}Brs{oZ+{7Y2@{Y(=Cz5&Z0PT1Lm?Nx2}z@^=Wis=wg7Rovd?wW z7c^sy(^XeHNa`YsG9o3bON&Z8zLYK-9^o=Eb?0dFPpRgIEu;^g>JvYMmLS;IRXAfg zmEXkPP@9wJK{$@S-%OU&GkBwU(Vy(xk0x8$k=%CKvbE_!?*pB6v z0=BK^{r7u#u(y&W8yfF$JQdZ7Z~L)+99nUo!bswM^t^a-1*2`k$%lEGtT&}^09;Oo zdmgccj&OsgRs8kt!Fg`(UM0&}YI61`pSo|$7Qmbp^SPQkC3dZ2LeO{#4N`-Of-iiZ ztVZkgy1|6l^DItrOXVq~ZGf`YCZ2lB^2O9u1QrF*9#ajQRD%%r$Tb*fU7X_M$y5S6 zU@D>*IpuUJY@j*9Bm%YXh{ znSC>UFoB|$xAySar=6H1Dvm_r!+vHQcIGf9IYUA{Qb322wpy%&tMj0Mfi30<96BH9 z8CEx=X7ua{n-(b%!T4ALr(}IYzoXMl;kzI2jvxqMcdaJczK_p5_;xc9KAU4V=qTgz z*7~N%p2LmUv=@gn;@H2y<_8zB->7xv%sm@IxL>YbgZ z5yYGxc(3btior(8k)t&BN(oC*2t-x0?<%F0oI1hoSkTSyQkU~%e%NF*5y$ye zp7K_#rSAZ)|iGPebT#LG7V0{GMjdh7?X2`3KO$@0r}5UZ9U* zZzQP^I$T3x0mw+aZSsHw0n*lR;5_ zQ`S(jYX8H0o!;6XVK?&!9Pfhq9Q{zJpQ(R^@I64ohS(Jc~h& zE|b)?WyrUmV8b(Fg_q;u$YcfF~u(;A28aWBPEg zDh9})JmBNUbr#zg-fXT;Z09J+wMKoH_hyukv0$%!y+NHXD+_1tk2Ah_#Vjp$I=!?3 zaN4a`JR|DOJPY)4f$GdxJZI8VW=FogYO?5G4wbEA65&aIT<{7zPw0v<+dBEHci}r2 z@7UejfdzgX`fO@-xOOBKK+;ibTpsK76N^J(|nGo_rb zrmj1fDG)Ut15kP}3!9(@j6SBu9l{lhcZZte?QUezI?LA(-WO8v&pFYUrlS^3rZCY` zJMDK9M7SS~9?eKP%Dw5>UU}wZ((pchnhA4a%Xz9WdG?7ipKXmTiOn)(^b;DNpnHK} zunRxJFtOJ#QInsgK85zb5w7t+4m2mn4^964S*#U7ewI6^S`7tN5t`5wcssai0H1M* z1pEV|z)^)gH%%iDJV3&|+~Fu2=Xi#km&dhbYq6AV!E6DLT+8J^V-%W41q!=3Y`-;L zACE#7fH6Ei%*iE^p|EgB9H**69GMQ=jcKa$cQxo;cy#K??Y4AzNMW5{k7{aS1G`q> zZ33BNXPhiM9{Ph)1;XxB2?xqJU4#v7Og@Rpef$k3Zn~pFcEa((Z$d|NmM5V|?{R%< zijH9Ztdk-91{2cD?E;l~8vKS=#k!38lo^qa1dpeR+hUd(uS!!4?pvgr0QN+exfC9{ z4H0dL1sg>Rw}_eD;r@&tSUup~&L?V)CG3jH9}=?z4J-A1BC(|D*57Ip!^lrGccT8R zxkI=bPkdh1`NzaU^{Q~b^I^CI4eLiVuNTTszvVxO)E~gwA&7V6IsKt{l~uPveLKIM zAcnm<6`ZC-##e1=R&AfnN8Tg$Zivw-ML{!sXEz&a@g>6E%Ga zeeI3TiG`eq6n(FoL_7}&h(<%F$J%B`zkj)3d`s4%y12pLt>^hc!N9h_Cj_rlU0mTQ z|MQ-3N4$=loPO|++@&-}4zf8~@NFCn-<%&LgiUH0^vdpFo<(>nrp`N!5@ky1a)lb1hQB($s3Zp=g8NcXQiqss8ID&MIk!8P~ zr3sQNV92M5?|^vJ9XaC9q`Xt%wBZhwF#$Pha)Iwk+!Kwz~h-Sj2r^)4Ynl=tRIDf?Gq(T7_*@lyTfIJT8JZ3pV;xzwtt+1`az0vpr9YG>_@oRN? z1O?a)2ywRIYXcQ$aN+W5F4aXG1QnAtr zcRu(GNqral5>>OTtmyKXqh_~u6Z@D#*8|GX!~rGvl3tx1+WIcpvEl(8jU)dD>in-& zwY2r33Vax(!K~?rx0f(t_mUqEU_KV#)mlpn`Cf5Kx};35vY1W%Y>VZ4ufTG4(FWNB zf|oO>+giWUi!;e%UIn4UGJ(A0YCV}}O^54%ODl9lSK*qmd zt1`hq(k871I%43zdHNiAa2?Wi9@)i;Bw@k;g&Qe=ngNR}F-Q&EvU~KasA}J*`xoFD z4bzH7V+%TxL+s*D!0^CNM!ff%0?xwKBivRVa8g=#iz)b5tshy^@RJXpr!@?*mL{m} z{5lU0`at|XN{fE*kjz~BW+X*^cB_s@$YydC=3ZWY?7cxMX~9*$m&`>EmNN+hbQzSF zsf#NFoeRk09XgUyn|%d1?Z1)67kUYoyt2_HpGJHgxLU$9zW=iKqk}iRQ_wb=WGg&x z8jYc7kR3!q?80vys@fv%1QV)SK}>cgIJ$XQy(Y_z%ZxaotR3Bm97GxhmcNum$^?hw zkim4bxvk@N#!De2@`1ZKb*3?&@f}A(EBqIw)vBKx@<~23h!gLJ>m-G6T%GdP9_`zR ze>PWBrSN{j&{J>KA_CNgL3tCff=8}LJ3;nLZnp@VYug<$bXBoVwyc;U(WcJ!2q=He zUQDfRl@azB5E$1|uegbs1?&!M4s7ltA=$KALSsHU=q7pbm@WTVY?7+-mch?@P=L&L{8B{cyQhJY-EtwS%ut2;*g$&o_t1rT|^!tpCTQQqr@Gy{U@=fEQ=%ua6&v(UZ>^lK_cM_9lr`s z<_29JG?t+QbAJ%vLPI|RF7~`aY^30K+!eeRO`peV3r$3awFU`N^ zQ>x@Pq!~++F2D3NA^5VPo;crtg*45LE~rzm#pFUjPla+rwOsR0uMAlyyqP`&S@6oAIECfc0p}Hc5Y{pG)T?r>j*R(qMAZ@2tF(%@ z1;e-}sMHL?%L`A3Ah6JKo+%8U=>=lAruLN=Xv{|g`yiqhPh>FhaafbV`N7(0gDCv} z4^+b6wF#{!EiKrGi2MxLk!UbP*uAMBh&sJ4IOh;C6%PxHrTsRtUIGk+EW*REV~|K% z+RbqKLwT^zukvMlQ0Fol^Uwh^$i?|G7-Sp=mRu?HR{{{0`~2j;M|EK3w82a9*5##So1dXb=?? zdU3|*dJ04j2q9I)X)$x7XX)_A@X6Ywt`>}Dtp|~tP{#2aRA^xBAGylKr_B2iWG=i_ zz!`4%d~;>=JJ{0d`{Q&);hS_m-b+tDb39Uy6QF}zAK-k@+bndHecTo~6!t9p`(z)( z@t3Zoz0IHrpmuga&Q)&=YL+|H?3YaBeZJ$( zKR4KD=lgK@`|zZmb4~LdJqBOxtez)9M>{9as3e}ZO>4cgoFNR!46IeQjbblRPn+N= z@P#I;iAG>d(5VBvk%Kq&4wlKFmM+2ob1a}^( z`iUs{iPRNPM)}6blH&_Kv{ZUIv^BJege?tDPRAQrjA^RbceBsvIy5w2S9Xe|I*mZw&FS%$ zjQe0Zxuh-W1ZpxqCYt?VEHmtO=+bNSVE>iRy9cbam#&|tN#l)m+_2Cmx)bw0$7SyG z#$oTx_lB`Eu-28T%A6Zh%d&b8ne;cqDsvlVY)S$HKNY3BSDv=r_`39RzWw;M4+WDW zC7FydOu`*F6_>1fsfvX+gefsD2$9Y8;gf{G@;({?kQkar94dM7lX;T%v#k_k1yR{a zSC6v+yit1a{AyePBRNy5?K2Dr1_uz=G$iG<`U07BV4V9VC(a-n_p{JDr*Gjql~(se z3GP=FFHXYT8QiaiJp2Z_d&fk;LePI>fo_H=>#Dn{nYAX<;8xxT>yL$XmLDw*l9pq( z-0yGIza?!agGYqka{-jAyEV$rNU0VR#_E8d4N<=l ze!}k=2d3B?r#SKfoWN%phH>U$l1g6zf!TIq4B2c?nN+fOWU>|15G3`f?MjWj70tbg z^h@(9PDal_l@D9p+gRplqOeA2Cu}|GpG;jhe)g`A_aMf1guA;yxL~L}qvh}jlWN{6 z_UR$WKE723%?&_<7GQtS4!<+m<{kxRZ1?3-W=%-3y;sEFs$@l3d!*;yAEO`Wv zSR6m5eY*Xci*IYs+$iAt-torg0?Ol928*;$3WfV#)*3-Yx6QrCO*ie{HQ7JVqxvXn zWIt`Ddv_$$@_Mb_UGF^4{^LS*yRubDzb7M+&FR4_n#4FaB9ObPEVdi1#R1a=G zRtX)dhW=L%@hUvBP9}eBW(@9k?Di3M47aeoe9Fu=gQM+%-J<>WkaCD^2E ziKh%#$3LZR7c&n_ris$D9{e3pJcU3cKCB~66YG-P+D_d(XKdNskwHKC#4n>>XqHjnZjZ9OVq z3Kh~XryPA(8(l?*Ct&_n?hz#(<|mZ(MK~R4Y2J-o$8OS5Ik$-;g2!y2lao-gyOZn);Dl7??Ps_CWqYpS2+?Y$EqH(fe_l z+x9rJXq<@-oBcs2EIPGK3kyOT>oUg<)@5ef#eDYER^>r^aKu$y3-h=;78bm3o&`7F z%DmKhhuW?$w`Fn90FoNIy__w7@@Z{BQ=dS(B=X)TNRI}Itek^Mi-Cj8cl~C@y645S z4nb`6&ll3IZ9Xv9U$rhso27dHDp!Wl6l-2GGBHiw(JRNrpwAun)DmD6?Moz`;n*F; z-+>nzZEEk`B*Pf#LfW88yh}{<*)it;^7KB$1ewJrLJ8StnY0|zzz}<7n8eubXkI_Eo(LqvUgbWy;XRtel5Uv z`0KOPYul$^7R_mn-)cV$@NJL9A1vJ>!A*Sx2qiBu90$;ir)L0_RkGCT8rY2-ltQ^> zDj3PN?iUbIv=8++TFi6shwb0V1sHd8h#hXS~~1pG-8` zW*=>5gqlgMyViR+xTo6&4^=)JUAee@cf5_>H4t<&jaI_J#;0_U0*!C93> z^SVW%<~p*L^#|4;*RK6w#$Q8oCg=#kKO{)RP(68oor432fZ|sj{TsJw{=d0RRBM-( z_Kd~W_5_ItM{(9*XB3?&5Hk=t6|sldPbXM{gHMntx9P%j?BeE8r6*kB@6P=2TsfLI zUmP6+2)=kV1w&CkzbvBw5&SJS(Eca$V~&pb`ES;icJr@K&qaMY@LnK8DY7E!!Rf5r(45sJ+jDBC6m}^urIP~; zr5&->rqiM2Vzco-z1eyOf4HI62X@g(@IGxLI}=`)(LM{O>B#L3?um6gO52X1bG=2C0(d4wZwZ4pxGW{PsI&KcgvTBCoV{^= z3Cw~BxeOW(Aj#=?7n_2Z!gq>zjKga=S_DYqO3{OxwRTG#SPeaiJ0F=glAX0`ZLi%D zeUT>Ysb9l|{UN9{HNndUGun$Zppw4CNz{rrB*xZe!=(N4ZIVOK6IIyj6;)sO!je-b#0 zuewlTP1=$}FJ7EgGf=Pm>9(}ZVVv}p-SG!Zx3E7B>yz6Mh`5s8Cg}A_jXc6TWznR( zmrI^S-L#G2Ze8{jjp1mj1*q7?4YwMDpyCMC6=f-}69v7*kf8y*jZadFEGOl(WKE05 zG{oQn;l6p8vQoN9W?4}em}8E^R}wt2_4ISfdz0)958;-Tg!m0H38J>kdz$-NBHG@y zD@*&4;!ITfmXE5MXFT|y;hdcv1y|bd-Wa5!x*As799rx>X!gnnTQYY9gKTaiT0@0; zTy2SC2bZR9Y7r6r21pi0-F{Y8B>_L+As#RU_GdN%tYvhxEd)fxeBBj?~rwsW|#X*^D&O@9Gq#`FQ zXX#v_ARmL2)TlaA)Z39T(0T>z`pgoMiR`mQ%^yT+oFR$YXKj)2Z5-bIGdKYB5s6a- zIQX&f{N|=HQE<9?2$tB!ef>q~n&rM9ozk#Gh z--yRtFy-5T3f$!9x1(9(aq4cKEOfP}JTIuzXWOr;;Wee)cP;lxuy_kD<8>DvB&xt( zPHa?@dJNHmRh(|sspaZnml-&VUZE5obHviboBu|aqfL6kVL?r5hKM{|6gU~h{g5iT z^r)XH9e@5HDrmV=e2Z1so3JpYW1vH?YyT3n|K+a01ndL44uGVnWDic}&^DSLvjmzK z8u|wXir0v~RyUZk@0(4W*^PuX5caNckr!7q8Gf`c)^pmiX+i8O>qfMy9n+}pvxYLN zTNNOcFmd#$Fd9yNs9@cnJ-f4%>E9G;Strzz|IJD<#nC_c`K99*Ew_q-mFMEU^ybPF z`A`M$$)2D7+{t=A!7J()!jf&p&K(BChyx|^s78up>*)LB&c=2yG9^sjM@)^z%zn73 z->`82i{GL3&;xSfC!%Q~Iu0Kdf~pGMlpd_YA4mHt;bS1}vGI~4<_7DpU#+qhP8XIV zfRGAYf7r+}Pau0@cc@16Ecy*zNTo-1j`AYUiqMz)jWZ6}-H+B4Xo##PWsX^{VE-Oh z66i3)9|#c(&I=Sp!dQ40f`iZ7Mj`(NV(a0i6&I?UZjLUx6K#3@yhiy@D>Bc)w99*p zYwQi#%=@O#W|7;DquH;nAuBIu*C)nu*>W^^;qY9d%=FpPq%dO`D8#^jtvS%dTI24k zmGr_w>#b@_>w@|zftNM2HPz;jOO#;H`)WS=RX(Q97kYTGMj){*$AKN@8N*|dBdpaA zKu|oZ(PWpB`k@}tHpUuHQ(Zw30s!w!X3xh8Onv;N$v_jEd*z87!Q&nm?PH8k#gsO1 zm~zs&2lw=jM`mRioDXW^DpeIOj61-xga-$}#lo>{aMjT&) z^dc{2OSitKJGGXRNNF$an*kEvlB-}s3v0Y@#z}fGIKZ_NzH4|k;|iaiwnaHFfhS6_ zMVSi9=~8xLnMF+cDYvyLQrmBk2CF3Ux%*O7loFK4-dR<%)j9%OVtt%?vBDv?Zs>%@ zfoPxxMD*fN0|uS`DLDe5sxM=LU)2{7M2h97NIuYFsdvxvXaQdh+wzE6!BF^?zD;y` z$%KjUtxA9kNLl#SzsILQ*u6l)ArjhIdGI#eHWl7(3r7^c3@=U&UmyW4;?(H?figfK z0TAEzq{Dzjc~hP?2aZs2jmklyiZUc1;+K{P|5yu6B_@IH@&DJH>;J~(1?O5!Fs14> zU)~qxaD$H|t`pP=(Vza+t2Q(+T%8}&->BT9U}U=GCWtGoIg+{b{#}NvD53r9{B2f3 zsR_oEV3x65rD12T_v2d{=8Epa#oS`qw~Trs9%a7`H)+cEQ{exs+a98=I)cE~Qvg<~ zJ&GW>fgmXp;@SpFCKX>{uq=*n!8j6vLe^4Sj%m{OP7-#mSR8%J|9CwW+H_~ies#@+1^SI_wHI~rWAE{hLbM)wdfYim0z93Z}KSF^r7XC@;20^RB z>~n=AJznhbPC`Gjsr#yp_p=mL6}3}V3@=5fyN2>BHpc%j-8~!nepgeJ*nwE`Q`+l? z4#^a9(E%JxKK>QA)@~Gw@;q^1O0~$nY4jtH<@@JclV|2W8vKj5`a8mR619skYZWjF z0W{lyN`#fTS%oQqh#mJ31`92I#ajXTp+w_A(XMF;=j_W!)qRJ%R$=%2<3~C+YC_XI zy{`Ie+FiC1Ru8edov#r}F%=3D@_#eI;4rNNK;srPL>uG}h6H4PDwHUr7bx)YX};k} z=hKWWVRr}APz{|+cR`9wAgY49>VtRP2-rU!Aj2S6^!wU#vE6&(Y3{^UEw+omKZj;W z$IBWN%<6vZ=@qgW{eIcA^{Qcy_$7WTfqJ{!#D!CXk;2(@aPGT~MrrtokWNa9Ox)&0 zEOYg_L7Igw&fCA+gzD)0rXZ90yDq(e%>3_LUI(yOCIJ0v=4-Q#0{Ss-bN@XfX@(*q z5V-$8SDY>;BnC+YHXCK_`dbx$^&Z^~G@px(6N3Kzz5n~Z!XVQylnk;CCHF`D8G~Vl zzeXB>=c0dx|G?^rL;qX!A4s@ExKDUM#Cpv= z-_$bR`)G_o12Q3~jC4^_046pDgI-2e9$5CMu|C)@hKu5#Lnk>o|8Euhub~rK+8iVV z5PpILD(tWhOysX zKDAsQRE--lI!f$$dhGP4K3E^{JQXLqZ(~8yI#hUY7R!=}=?m7zLnxEm z`xV-=s59INGq{FnUXAr3cY88>`h6d6#NdeoE0q}?7#Wewb&v|0`Z^rx>@r+YOQ zwJbbbgs`I_beZykNeemCg^VphIbS`z7tTJvO|i6)c*Lguk$yH*`EC$6|}2Lr*Hr_o3%puFUTVfik(MeG#Xq76}!0b>DEMtJ8G~9 zdmfKKm@wkXH5vV}O$)Q{O-0ntVwG<0u!0hVWbaH&e8AsgIMh1Eei@OHS_+yAc+C4I ziZgZLE>R`6_*vL>U@ar1!>hTt^B1m>JMa8 zPUKC0zrS>-{D?fc&;ma@XHg=nL^ke?fG+}9P?4Y&@p>%CB`Am_BbV*U4dVsi8OH9H)>SmVL=O}g%C}Q4%7c5hS(K)gtFggO za6oQ49HDfJHA4vkn#QhrVxX>I*?WRB*K$CDpd1q*vc=~GnMy_R8gL>?7XjEkza-md zIWebb%twP0|3tm>WL!}@8a3cDZ%$2~)$bA8{sUMpx3esR_lRbRt;#qSH)5UEWNM#p zuaEkOLkX_1%FgL6)4;!6>JSn381|q6ras=`8BWIC%u*?-?-LdmR3Bo5SEH6Qay0fO z(qe`GMYm&dr}6XJ&J#kLdp2J$H(!$PHH#K_5f6E0`U4-M-9#bV#X@{iRWoqjSV5H4 z1Am5q!RhIsxrvpyUl0DBe3f+g#p}i5MQVTK3#e%&U7_1Z)U(R8@n;9P8~MD z={d<5Au(H=d-%0Z)qh8>qm(Z0QTk0{wOz~ibl$F8F`(TAtZH>BW7Eh8swV;B%!OKw zFDG+sB7EP|3lU1nxV&Z%)q8|_J^cZ}KGBK&3pX?;g9fTX|3Ft&Fg}bz@Tdm+9ag)z zknr~4aEswL&p^(pu|;}JCC1kY`PYAv#2h#FSm(m1+_E)N3ln#OoU`iB`ju&JZ4#v> zr4enu8Qe!CxrMgP!w6@$oEAR>@7+ALmxD@udF zA-6v^v)huEr!2#bA^LTQtEOA%`^iS`8EKIQ`Q_;sL19LxZEJndTjG9`ZMn+BR2x#| zQjqJViKizYM(#`P|7bhdZWw42e^M=e_E>0CceA=Yd3wRhiRUiwmlHvCF4KWK_Tk_Z zTO$1%keadIy@nbu`V9<2#V<|;JB_xU;}O(kiAH^$?wbcgFA*z#L3k~_sAf7JR*hh{ zmXHu-H046N`e5lM$HVs#gGn$clc|*}L*FTPGgQ4-D!_dN4g5MSP?DCg*Mnj>pDP4O za*ugh-2ws~vOEf`e9T;i%Y$zP-<+CTSsz-Gew%ldIiT`xO*no|aYZp^T1^S*v3TIB zh1jQl9w2!k=BpWnP5toxuK>o?9PyKqBfHTd?$x_tw#SBbI$uBoWlM-C*G@$;kc!GX zJr&^07_XxDI*4m|wOp2pe6A|WEbf5f@n@3fc*lh!x5yleNOt&BZZm$QlzFK*N0Q(e z`dtHOrZiUfhlW69;!cL#wY?{2Soj~K&@8i&LWkSM{y^*wn}$Kp#qQYlFb-0!pNpBE z0Cqaq|6`SpF#(!YKL5R#DdH3kwrwwB0iVdX(@-ch8NS_oZl*=~>=)2PhE zuw$6X5B3`oV7J7NAvENOX zWTr$1&2|qdbl@LyafMau7;3wR0&0vaidZR2PH7i2#7lOA_YfnHG{BFP=X!tvWqw&o z;7iR8n$HnW$8mQ{dM>SdSu3U3Yj zS4Qcy>(JXi-Os;-sg}rW)vK3`!em|b>{|`DX8Dt-I1N05>uvtTN)k zOq6bE@x@e#Oy%AK5a-^YL=#465Ih9swu^=liuFD3$EYI7!C+nQ)FDtngL6Vac-7C^ zsQz4&A_I|n!_1{#*GPK(wXL1UZoEAF?4*9JeJS6s_g0tr$m{LbW8qK%`&WUpy5cwa z1tzpd1lOwj%O21bCVysH^OLhz4jB^YTFbi+QEmmOJfi0H!4Zxt-ohn&m&)pCD4M4H zp3Utg?+Yu^(yV>rD=DAhRdBWeA61T2k5^p8uOx8k`Sz+`?{YcJhg-f|U$OB)q=WNJ z8jB>>CFO?DI0Ow|hyF>(oKOCt8dUSBfm&cXMI35XNB6^$Xsi=QmGjmyB#$E^OS^D>G#IPq>%=0ve%tFeq_ihJso@CjVADd<#8sDG;>whwrgIWg$J6~ytWsjn?|E60UNYD3yLH@l{i|D+^Tk?;cT7UI; zU;WkNMJ>`IBt*)C!SFg;TlwwS@V0L(k(Wr{!pq7~pFrDx{h8be*33xS1L=Fyz2k!=`$JRW$wL$XcO;EvC zdiYF#>9*CboOf8VH;d!6_I1^86PJhD(}l<9n}DiKX?X4(KWTHGOxp7xv1VxRX2%eo zdy0rY4Zs*zp^2}~u>{-1Q9E}F*s9+d4FF~#7s9@7R*WFRq7&a0AJzdkzUlxSZs0y3 zgFDPF7L`>(x%M^PvU7Q7D@0fJ%U<~@(Mi^;brL6>;LyehERz#P?&$YE%-z5H?tz@4 ztQ0oSGHqyc(GSxez7;dUem9Zq9U^Kk*G@Dsg9b>1Yf+F@o!^Lm;P_9-T$SJh2m6^c5$aTz+DpT-j1Zd`coKx z_op`Nuk@k&dNfe-Pt+;z$Ics6D7J=x4*%&M(bB#4vZi!ZQg;yS?_qa*y*H?GWRFa` zqEWPhGWHWgzwfqhAH1u2O)^Rrpox+kak7pm5 zT`1R_70Kcg56*@#uB#30V4D%ld#>)Z)1{cZswplQ?tB{1!sYK8j4+?SKEe-_GXOr= zAs*rJzp>9_i@+{o>WoM^VR^}d_4(D)2LG88%xwCnhZt~J>LfZ>paF~!v5UWLKk4#+ z-9-xEUvc?=yo+aD?WlQKBodp|tqTs&2(t}qZ$H}w?BZard?ZSgr=^9%5dBC(Le$7C zk}VCM+RqZ1;D{}=gG7?-BjKzWzXoVooO}q-nTihi{lU72q;uqFOBikAOZs>ZcNnzy z^`q&kW3lPqi|-;!?z*PDF5SarlA#n!iX79#WLb)S@j@lTw_Psw(ql#tqq&@!v@vbM zYEZo10gskHl!4d*N{}|Nr2W#`TOGRQ-kYVUHa1|xGZMx22X|sB- zI9Si)2vA02po`8K=uqDu?E0x0{Rx9XW9CL!72nQfN!*W1tXS2+=h_jo>hkCkTc^La zleMsQTo=cWu(&-ea27k)25g%l>93T#9!XZs##h*c!EC^%cZ)vp-n4UyVT7NiR&l;x zGBkI5?Z$`V#1#j8gWkqZ#vVHMq!-^Gs-XNMWEEPooZXT`z z+srE>GCi^7)29O>Gx6VPf^WZ{6xO+VEf5x4GQ#-5X4xA<$wS0JdFw}8In_K|I%zs* zM>n6dxm~7!GL#yfgV2G#KbSeJ8LfB6JRi=4x7gc}egzTd(`XzJf8WN8u%&$Qb2@VZ zB@ZFjU>jF|uHK^Fyc6GZeWamoOwIG9ec+GJEHXEkIT`&63)2(75WLNiz`K>E>qPIL zS5Wx6P;_MAMZNC8kfR=V;qK`7uQ<8iKHZ^!QiNq!Q7uzoUy?=~sABCM+&N6q35biq zbq|OgquQf>rc$SB#_F?5Wk6hdYX0Lz*L9MhwQFThp1*1Jifz(26W3DyLTa)qT}7Yf z;r)X`{XV6#P24&wo@BYK!Sr75$V~QxXeAdD#@zI^CUpKn3k3gw_7_Jf8_pGfsL6W= z(BFx~0re(`hHLzLF)YLX7MAD8Z?haCJI=b0BrIVk$Qy^Ks~r&mAH#+Lhf#|&asCAbGoI_B>EEAk!ulNxf-hb<3Joc`cN(A~Lf(-q zCrJYAAAYn$&VbuUIi=J<8n9eK8PznXbd~a5ZfR@j5ZR|!PjQ2jdwZVdAPaLp`5I;A z`*x6IB}7zawF#aYTD#?Z6J^O8Wyza%6wkln_(7E0SS0v+80( zaka^JJH6S3&Vf@uZW*zvt@-e_g}lEIsDHFDe!;qmi})-3NsQ52sHH!j}a(3#KD4LLSUo~ zsBw1G5uYhTI82h`CBsqWK-V@Pjs)S$w1|Oya|N}BH?U~&ESzZm*YeaLV_k7HQI4vM zf437g=WPdn=kzz~DKdgTz%xvrH~>E8?Tbac?_T2UL(MaPPM);uWegL(?j zkhZ9ucys3f&d&C%qx~=zqr^EiHIbHctbmY|eAN>?@I58GI7V?r9vI0K2^y2%A!0#r z9wTuS(ih|nFn)E@;ePJuP%Emp`Mbe?K$lnz|6&KsF|o17Un`-ecqAYR9a`HsKZkgf z6i|yiK?MI_bw?f#<=VX=G`NgrkSyoEhSl!NrO@- zxwe#KsVs#;CQFt=DpDv*DYBO2duPg3-@U)z{k}iH-*4VC&pC6>dCxh|dFFke=l8tt z`MzReMiGzCIbQ@U4unr#0#!%tg3nzUW=*6RUcMNo>Sz!LFQk|2zk=ecl;7lJ`X{0? zpS+0}$dT7*8p+P=Opn9J*j$0$^vJDyz9XKeNcG3~wJtvI|ht1dW8FP%sd}I5^0c9sq?Q94SFmGSpoQivbR-JMeA= za}FSKfIAWm9KcEv2aq@*;LlbNr$y%g+Ml#les2zi%mJ$uI}XAX=8Ek96Xj|>$U(U+ zcP%v62H;zZL*#O=D&eaAg~BzJz+p7ufK|pddqaOFqd18AUnpD`xxZmx2!~)#KeAWQ zF9E@EM7ZXyImY#c>-jGRtud_H!r%z6dG5(UsT{zK&zk3f9NMZ7SIzf;{OE%J?@oas za6mDfARytaNI)J!4pV>{I=-O{azFst2ZpdDhaRQ}cnAIx^|jD&qsNWL-zD8I9r_>9 z{@?QK7fnB<7BF16=2Pf2JW%2X0>$q{AyF8lHWDb`pp8QB&_HUbB9W>9pEce4pI96N zNDKzq8>kmVq6U&d2s=kp7dRo9O7$esXq>U?=t~KN0H5z;Rvkhl2LuAAhG@Yx(VE&j zP#A434HO)+I+y_gAfi^3Lu3eG6$;@^K7_!NJt-s_403=$3i1sklOTtF=)l0W;AjpD zj8mfMN8yj3=bMf|r$7+4o_-EN2SErM2uho?!zv&!2m(A7uvY#EySl67pZ8zAIqypE z$B3~97aZEWK8YnPtdrqS&xI#!qlgKNkrs_h&w8)hkDY2U`ZBqsXs-AEmfMRXmZf58 z^1Jn7GY5qW&61UJ9;Q4_P==*FOty$hRaQ_K$J@A~l8+y9*HW>z7z!@iUSQ^Wu-RBL zMQOj;HAxujHZg@=Cz{T)lLh57ZSuuMB|cfiQ&3Sa>|%?${PQ|fL{1AtV|c%v#pQs8 z?ZFpD&TJSd`gARtcj9#65@jjUa=>z@=J^)giPOEqFa_|?+|}@vr%$7*E0zmLJvDu_ zCX&{NhyFEA3$(t2H{czy3i-Ml_K1$Y`}TQW?xLBX9ziVGz~l9dWdwW6ke_Ait-8UL z#gtJgszg)Rb9WE-%$K``G}KhoQ^T(JiW3NW8C!^-P(nG`jVcFR2Q6PtRWrbfhv|rl z{p3S;{4UhI*Y2Y%V{J(+J|q!hI@)b-jgu#`*kP@<+evNOCxze|<05|6vb^9?HCbfert5~0@+AVU zY}MZ2nqcoEs+bqk5sPNC+L{hc|95F?8K(9IQ`w^HAZJh*V$ioVS>q z1%+KzX39!L3Y)s+jcv-%?TtKZf;H>wmdhq*lZR<1F2y)Vv`D`#y!yZ(G`U4R)XKIh z(>C{OGCS4rVQ8O4Td2>!+M_L6i-#zbvoq;8+e443FFX)y^Lka~>kK+~6R|$Y+7YyF ziW=pw=yfv*NwDs?9DhZoCh2xlw@c3Le3u*tY*E*EM(>zaDdE6_+}3w1Rp<-3QXlf~ zhiUv#^}sGuyfYZBd^J2>nhJgNoaa>3f$cFu6|?e*Q>CZrSB1i7>+2D&;#&$_Kdw9( zEXr7#5~P+0imSQGTY=@+PSJ-ix6DH97%Pn$E{4!CT%PFGCmW%S%GTNM#4qQn?Y6HU zd&|dnMueK{rNmH@Q*UlGVc?qeiT?GaC!g_3tI}=<$%KT8oEi_?DsoEH*rU zT2nMR+tLKxkj_6bYl%Wh=3Rce7>8FxsD6P1c+GdjAY zI<(V7->5sos{Kt$zDj15qtmetKi|Q~g4a^pv!4l;gWnx>8ql{Bu$a}Mj_UOtAbBmGHnWY}ZQc)bUmTL-V|6jl@ai}0 z!o3i@(3`)b+*8BT2S!x#d8jNcw3+1+cV@#$DZ$NMok!YE@Y{Nw1Z@#8vfL^dNc*FH z?42v-?R*y{an4=NLH}uf!2GRL$6yF7>B7g40d=t5WlS&gVt@6*PQ`BX>}gct7sa5* z{JH&Rb36Jin6_t&;AUl_H2LJ@+tX(K_VCh_d1kad3Jtbs?yH1;$om4#YjMeEW+$|M zig0yac1AK+Ks^^WpSdn+_vm9drZ%E~dU9B5P^q|jZ|~@xH^h?nGV_6A2BB5@;fM6* z(}o?=`K@hhhYn1qes!-2zxAyQOz(D|=+zA3A_>ZqYdy9^$4)z~HbtSb`4PR2#2JAZQWLXf%poO3=ZZnBWO0 zQv=99vjFG$QI=3k=f9uSN_Cl=_3W03ogS?UQz(8KextmQ=}BN^`=nUA5YeyBU+}>k zx6C$G;WJ)ud{Zz1qv1E2?}Ts255DHtqnvE?yjvM6i`hMRbXr%ww&8Poc>B6(vr(yWL08HbH|39(dJ9{Qmb{lZSJ&94P89Z>mn9PP7sO_=N=o9L zvP!?K@9nn@OFQw{&S%oJ=uX@mu8#qht9YG!MSI}hTiw1-zooUmDs$Nju5nHrZh^b^ zoV*@01%C0kvU+151*{pP2^={5?iI3=n4_-M>VXU3;(mnx4rI8S?f zXGO*pTzWN*4cS(fdC|6v7?*A*H-W?X&bohPQ_rn@wKHG%>%1*6h!hYM0^AIPP&ybL MG)P6o)RqAHHym=NWdHyG literal 0 HcmV?d00001 diff --git a/ra-preguicosa/ra-preguicosa.tex b/ra-preguicosa/ra-preguicosa.tex new file mode 100644 index 0000000..65c23e0 --- /dev/null +++ b/ra-preguicosa/ra-preguicosa.tex @@ -0,0 +1,13 @@ +\documentclass{maratona} + +\begin{document} +\begin{ProblemaAutor}{}{A rã saltadora preguiçosa}{1}{1536}{SPOJ - RAPREGUI} + +Sr. Rã vive em um pântano em forma de grade retangular, composto de células de mesmo tamanho, algumas delas são secas, outras são somente lugares alagados. Sr. Rã vive em uma célula seca e pode saltar somente de uma célula seca para outra célula seca em seus passeios pelo pântano. + +Sr. Rã quer visitar sua namorada, Sra. Sapo, que também vive em uma célula seca no mesmo pântano. Mas Sr. Rã é preguiçoso, e quer gastar a menor quantidade de energia em seu caminho "saltante" até a casa da Sra. Sapo. Sr. Rã sabe quanta energia gasta em qualquer um de seus saltos. Para cada salto simples, Sr. Rã usa a figura a seguir para determinar quais são as possíveis células alvo de sua posição atual (a celula marcada com F), e a quantidade de energia correspondente no salto, em calorias. Qualquer outra célula é inatíngivel da posição atual de Sr. Rã com um salto simples. + +Sua tarefa é determinar a quantidade minima de energia que Sr. Rã precisa gastar para ir de sua casa para a casa da Sra. Sapo. + +\end{ProblemaAutor} +\end{document} diff --git a/ra-preguicosa/src/checker.cpp b/ra-preguicosa/src/checker.cpp index 2255902..a60b399 100644 --- a/ra-preguicosa/src/checker.cpp +++ b/ra-preguicosa/src/checker.cpp @@ -1,12 +1,33 @@ #include "testlib.h" -#include - +#include using namespace std; - -int main(int argc, char* argv[]) { - setName("Set the name of your checker here"); +int main(int argc, char *argv[]) { + setName("compare files as sequence of lines"); registerTestlibCmd(argc, argv); - return 0; + + std::string strAnswer; + + int n = 0; + while (!ans.eof()) { + std::string j = ans.readString(); + + if (j.empty() && ans.eof()) + break; + + strAnswer = j; + std::string p = ouf.readString(); + + n++; + + if (j != p) + quitf(_wa, "%d%s lines differ - expected: '%s', found: '%s'", n, englishEnding(n).c_str(), + compress(j).c_str(), compress(p).c_str()); + } + + if (n == 1) + quitf(_ok, "single line: '%s'", compress(strAnswer).c_str()); + + quitf(_ok, "%d lines", n); } \ No newline at end of file diff --git a/ra-preguicosa/src/validator.cpp b/ra-preguicosa/src/validator.cpp index 1b212e4..bf56f9e 100644 --- a/ra-preguicosa/src/validator.cpp +++ b/ra-preguicosa/src/validator.cpp @@ -7,12 +7,13 @@ using namespace std; int main(int argc, char* argv[]) { registerValidation(argc, argv); while (true) { - int C = inf.readInt(1, 1000, "C"); + int C = inf.readInt(0, 1000, "C"); inf.readSpace(); - int R = inf.readInt(1, 1000, "R"); + int R = inf.readInt(0, 1000, "R"); inf.readEoln(); if (C == 0 && R == 0) break; - + ensure(C != 0 || R != 0); + int Cf, Rf, Ct, Rt; Cf = inf.readInt(1, C, "Cf"); inf.readSpace(); @@ -30,12 +31,14 @@ int main(int argc, char* argv[]) { int C1, C2, R1, R2; C1 = inf.readInt(1, C, "C1"); inf.readSpace(); - C2 = inf.readInt(1, C, "C2"); - inf.readSpace(); R1 = inf.readInt(1, R, "R1"); inf.readSpace(); + C2 = inf.readInt(1, C, "C2"); + inf.readSpace(); R2 = inf.readInt(1, R, "R2"); inf.readEoln(); + ensure(C1 <= C2); + ensure(R1 <= R2); } }