diff --git a/.gitmodules b/.gitmodules index 32ce4983bb0..23a93ea6652 100644 --- a/.gitmodules +++ b/.gitmodules @@ -76,7 +76,7 @@ url = https://github.com/google/snappy [submodule "contrib/cppkafka"] path = contrib/cppkafka - url = https://github.com/ClickHouse-Extras/cppkafka.git + url = https://github.com/mfontanini/cppkafka.git [submodule "contrib/brotli"] path = contrib/brotli url = https://github.com/google/brotli.git diff --git a/contrib/cppkafka b/contrib/cppkafka index f555ee36aaa..b06e64ef5bf 160000 --- a/contrib/cppkafka +++ b/contrib/cppkafka @@ -1 +1 @@ -Subproject commit f555ee36aaa74d17ca0dab3ce472070a610b2966 +Subproject commit b06e64ef5bffd636d918a742c689f69130c1dbab diff --git a/debian/rules b/debian/rules index 7218e196baa..5b271a8691f 100755 --- a/debian/rules +++ b/debian/rules @@ -101,7 +101,7 @@ override_dh_clean: dh_clean # -X contrib override_dh_strip: -#https://www.debian.org/doc/debian-policy/ch-source.html#debian-rules-and-deb-build-options + #https://www.debian.org/doc/debian-policy/ch-source.html#debian-rules-and-deb-build-options ifeq (,$(filter nostrip,$(DEB_BUILD_OPTIONS))) dh_strip -pclickhouse-common-static --dbg-package=clickhouse-common-static-dbg endif diff --git a/docker/test/fuzzer/run-fuzzer.sh b/docker/test/fuzzer/run-fuzzer.sh index a9905d274f2..8cfe1a87408 100755 --- a/docker/test/fuzzer/run-fuzzer.sh +++ b/docker/test/fuzzer/run-fuzzer.sh @@ -161,7 +161,7 @@ case "$stage" in # Lost connection to the server. This probably means that the server died # with abort. echo "failure" > status.txt - if ! grep -a "Received signal \|Logical error" server.log > description.txt + if ! grep -ao "Received signal.*\|Logical error.*\|Assertion.*failed" server.log > description.txt then echo "Lost connection to server. See the logs" > description.txt fi diff --git a/docker/test/performance-comparison/compare.sh b/docker/test/performance-comparison/compare.sh index 9e1780f247a..5e805b9ef0d 100755 --- a/docker/test/performance-comparison/compare.sh +++ b/docker/test/performance-comparison/compare.sh @@ -514,7 +514,12 @@ create table queries engine File(TSVWithNamesAndTypes, 'report/queries.tsv') ; create table changed_perf_report engine File(TSV, 'report/changed-perf.tsv') as - select left, right, diff, stat_threshold, changed_fail, test, query_index, query_display_name + select + left, right, + left > right + ? '- ' || toString(floor(left / right, 3)) || 'x' + : '+ ' || toString(floor(right / left, 3)) || 'x', + diff, stat_threshold, changed_fail, test, query_index, query_display_name from queries where changed_show order by abs(diff) desc; create table unstable_queries_report engine File(TSV, 'report/unstable-queries.tsv') as @@ -592,9 +597,11 @@ create table test_times_report engine File(TSV, 'report/test-times.tsv') as -- report for all queries page, only main metric create table all_tests_report engine File(TSV, 'report/all-queries.tsv') as select changed_fail, unstable_fail, - left, right, diff, - floor(left > right ? left / right : right / left, 3), - stat_threshold, test, query_index, query_display_name + left, right, + left > right + ? '- ' || toString(floor(left / right, 3)) || 'x' + : '+ ' || toString(floor(right / left, 3)) || 'x', + diff, stat_threshold, test, query_index, query_display_name from queries order by test, query_index; -- queries for which we will build flamegraphs (see below) diff --git a/docker/test/performance-comparison/report.py b/docker/test/performance-comparison/report.py index 26a3cf61e7e..176cb2e90fe 100755 --- a/docker/test/performance-comparison/report.py +++ b/docker/test/performance-comparison/report.py @@ -63,7 +63,48 @@ p.links a {{ padding: 5px; margin: 3px; background: #FFF; line-height: 2; white- color: inherit; text-decoration: none; }} + tr:nth-child(odd) td {{filter: brightness(95%);}} + +.all-query-times tr td:nth-child(1), +.all-query-times tr td:nth-child(2), +.all-query-times tr td:nth-child(3), +.all-query-times tr td:nth-child(4), +.all-query-times tr td:nth-child(5), +.all-query-times tr td:nth-child(7), +.changes-in-performance tr td:nth-child(1), +.changes-in-performance tr td:nth-child(2), +.changes-in-performance tr td:nth-child(3), +.changes-in-performance tr td:nth-child(4), +.changes-in-performance tr td:nth-child(5), +.changes-in-performance tr td:nth-child(7), +.unstable-queries tr td:nth-child(1), +.unstable-queries tr td:nth-child(2), +.unstable-queries tr td:nth-child(3), +.unstable-queries tr td:nth-child(4), +.unstable-queries tr td:nth-child(6), +.test-performance-changes tr td:nth-child(2), +.test-performance-changes tr td:nth-child(3), +.test-performance-changes tr td:nth-child(4), +.test-performance-changes tr td:nth-child(5), +.test-performance-changes tr td:nth-child(6), +.test-times tr td:nth-child(2), +.test-times tr td:nth-child(3), +.test-times tr td:nth-child(4), +.test-times tr td:nth-child(5), +.test-times tr td:nth-child(6), +.test-times tr td:nth-child(7), +.test-times tr td:nth-child(8), +.concurrent-benchmarks tr td:nth-child(2), +.concurrent-benchmarks tr td:nth-child(3), +.concurrent-benchmarks tr td:nth-child(4), +.concurrent-benchmarks tr td:nth-child(5), +.metric-changes tr td:nth-child(2), +.metric-changes tr td:nth-child(3), +.metric-changes tr td:nth-child(4), +.metric-changes tr td:nth-child(5) +{{ text-align: right; }} + Clickhouse performance comparison @@ -111,11 +152,14 @@ def tableHeader(r): return tr(''.join([th(f) for f in r])) def tableStart(title): - return """ -

{title}

-""".format( - anchor = nextTableAnchor(), - title = title) + anchor = nextTableAnchor(); + cls = '-'.join(title.lower().split(' ')[:3]); + return f""" +

+ {title} +

+
+ """ def tableEnd(): return '
' @@ -238,12 +282,13 @@ if args.report == 'main': columns = [ 'Old, s', # 0 'New, s', # 1 - 'Relative difference (new − old) / old', # 2 - 'p < 0.001 threshold', # 3 - # Failed # 4 - 'Test', # 5 - '#', # 6 - 'Query', # 7 + 'Times speedup / slowdown', # 2 + 'Relative difference (new − old) / old', # 3 + 'p < 0.001 threshold', # 4 + # Failed # 5 + 'Test', # 6 + '#', # 7 + 'Query', # 8 ] print(tableHeader(columns)) @@ -251,15 +296,15 @@ if args.report == 'main': attrs = ['' for c in columns] attrs[4] = None for row in rows: - if int(row[4]): - if float(row[2]) < 0.: + if int(row[5]): + if float(row[3]) < 0.: faster_queries += 1 - attrs[2] = f'style="background: {color_good}"' + attrs[2] = attrs[3] = f'style="background: {color_good}"' else: slower_queries += 1 - attrs[2] = f'style="background: {color_bad}"' + attrs[2] = attrs[3] = f'style="background: {color_bad}"' else: - attrs[2] = '' + attrs[2] = attrs[3] = '' print(tableRow(row, attrs)) @@ -281,7 +326,7 @@ if args.report == 'main': 'Old, s', #0 'New, s', #1 'Relative difference (new - old)/old', #2 - 'p < 0.001 threshold', #3 + 'p < 0.001 threshold', #3 # Failed #4 'Test', #5 '#', #6 @@ -498,9 +543,9 @@ elif args.report == 'all-queries': # Unstable #1 'Old, s', #2 'New, s', #3 - 'Relative difference (new − old) / old', #4 - 'Times speedup / slowdown', #5 - 'p < 0.001 threshold', #6 + 'Times speedup / slowdown', #4 + 'Relative difference (new − old) / old', #5 + 'p < 0.001 threshold', #6 'Test', #7 '#', #8 'Query', #9 @@ -519,12 +564,12 @@ elif args.report == 'all-queries': attrs[6] = '' if int(r[0]): - if float(r[4]) > 0.: - attrs[4] = f'style="background: {color_bad}"' + if float(r[5]) > 0.: + attrs[4] = attrs[5] = f'style="background: {color_bad}"' else: - attrs[4] = f'style="background: {color_good}"' + attrs[4] = attrs[5] = f'style="background: {color_good}"' else: - attrs[4] = '' + attrs[4] = attrs[5] = '' if (float(r[2]) + float(r[3])) / 2 > allowed_single_run_time: attrs[2] = f'style="background: {color_bad}"' diff --git a/docker/test/test_runner.sh b/docker/test/test_runner.sh index 561117492b0..d9bca8f0037 100755 --- a/docker/test/test_runner.sh +++ b/docker/test/test_runner.sh @@ -16,7 +16,7 @@ if [ ${CLICKHOUSE_PACKAGES_ARG} != ${NO_REBUILD_FLAG} ]; then fi -# In order to allow packages directory to be anywhere, and to reduce amoun of context sent to the docker daemon, +# In order to allow packages directory to be anywhere, and to reduce amount of context sent to the docker daemon, # all images are built in multiple stages: # 1. build base image, install dependencies # 2. run image with volume mounted, install what needed from those volumes @@ -26,14 +26,14 @@ fi # TODO: optionally mount most recent clickhouse-test and queries directory from local machine if [ ${CLICKHOUSE_PACKAGES_ARG} != ${NO_REBUILD_FLAG} ]; then - docker build \ + docker build --network=host \ -f "${CLICKHOUSE_DOCKER_DIR}/test/stateless/clickhouse-statelest-test-runner.Dockerfile" \ --target clickhouse-test-runner-base \ -t clickhouse-test-runner-base:preinstall \ "${CLICKHOUSE_DOCKER_DIR}/test/stateless" docker rm -f clickhouse-test-runner-installing-packages || true - docker run \ + docker run --network=host \ -v "${CLICKHOUSE_PACKAGES_DIR}:/packages" \ --name clickhouse-test-runner-installing-packages \ clickhouse-test-runner-base:preinstall @@ -50,19 +50,19 @@ if [ -z "${CLICKHOUSE_SERVER_IMAGE}" ]; then CLICKHOUSE_SERVER_IMAGE="yandex/clickhouse-server:local" if [ ${CLICKHOUSE_PACKAGES_ARG} != ${NO_REBUILD_FLAG} ]; then - docker build \ + docker build --network=host \ -f "${CLICKHOUSE_DOCKER_DIR}/server/local.Dockerfile" \ --target clickhouse-server-base \ -t clickhouse-server-base:preinstall \ "${CLICKHOUSE_DOCKER_DIR}/server" docker rm -f clickhouse_server_base_installing_server || true - docker run -v "${CLICKHOUSE_PACKAGES_DIR}:/packages" \ + docker run --network=host -v "${CLICKHOUSE_PACKAGES_DIR}:/packages" \ --name clickhouse_server_base_installing_server \ clickhouse-server-base:preinstall docker commit clickhouse_server_base_installing_server clickhouse-server-base:postinstall - docker build \ + docker build --network=host \ -f "${CLICKHOUSE_DOCKER_DIR}/server/local.Dockerfile" \ --target clickhouse-server \ -t "${CLICKHOUSE_SERVER_IMAGE}" \ diff --git a/docs/en/interfaces/formats.md b/docs/en/interfaces/formats.md index 5abf2bf9ff8..d22a52f1f1f 100644 --- a/docs/en/interfaces/formats.md +++ b/docs/en/interfaces/formats.md @@ -1015,7 +1015,7 @@ The table below shows supported data types and how they match ClickHouse [data t Unsupported Avro data types: `record` (non-root), `map` -Unsupported Avro logical data types: `uuid`, `time-millis`, `time-micros`, `duration` +Unsupported Avro logical data types: `time-millis`, `time-micros`, `duration` ### Inserting Data {#inserting-data-1} diff --git a/docs/en/interfaces/http.md b/docs/en/interfaces/http.md index ab1cb4b4d7d..a5e7ef22558 100644 --- a/docs/en/interfaces/http.md +++ b/docs/en/interfaces/http.md @@ -76,8 +76,11 @@ ECT 1 ``` By default, data is returned in TabSeparated format (for more information, see the “Formats” section). + You use the FORMAT clause of the query to request any other format. +Also, you can use the ‘default_format’ URL parameter or ‘X-ClickHouse-Format’ header to specify a default format other than TabSeparated. + ``` bash $ echo 'SELECT 1 FORMAT Pretty' | curl 'http://localhost:8123/?' --data-binary @- ┏━━━┓ @@ -167,7 +170,7 @@ $ echo "SELECT 1" | gzip -c | curl -sS --data-binary @- -H 'Content-Encoding: gz !!! note "Note" Some HTTP clients might decompress data from the server by default (with `gzip` and `deflate`) and you might get decompressed data even if you use the compression settings correctly. -You can use the ‘database’ URL parameter to specify the default database. +You can use the ‘database’ URL parameter or ‘X-ClickHouse-Database’ header to specify the default database. ``` bash $ echo 'SELECT number FROM numbers LIMIT 10' | curl 'http://localhost:8123/?database=system' --data-binary @- diff --git a/docs/en/operations/system-tables/stack_trace.md b/docs/en/operations/system-tables/stack_trace.md new file mode 100644 index 00000000000..b1714a93a20 --- /dev/null +++ b/docs/en/operations/system-tables/stack_trace.md @@ -0,0 +1,89 @@ +# system.stack_trace {#system-tables_stack_trace} + +Contains stack traces of all server threads. Allows developers to introspect the server state. + +To analyze stack frames, use the `addressToLine`, `addressToSymbol` and `demangle` [introspection functions](../../sql-reference/functions/introspection.md). + +Columns: + +- `thread_id` ([UInt64](../../sql-reference/data-types/int-uint.md)) — Thread identifier. +- `query_id` ([String](../../sql-reference/data-types/string.md)) — Query identifier that can be used to get details about a query that was running from the [query_log](../system-tables/query_log.md) system table. +- `trace` ([Array(UInt64)](../../sql-reference/data-types/array.md)) — A [stack trace](https://en.wikipedia.org/wiki/Stack_trace) which represents a list of physical addresses where the called methods are stored. + +**Example** + +Enabling introspection functions: + +``` sql +SET allow_introspection_functions = 1; +``` + +Getting symbols from ClickHouse object files: + +``` sql +WITH arrayMap(x -> demangle(addressToSymbol(x)), trace) AS all SELECT thread_id, query_id, arrayStringConcat(all, '\n') AS res FROM system.stack_trace LIMIT 1 \G +``` + +``` text +Row 1: +────── +thread_id: 686 +query_id: 1a11f70b-626d-47c1-b948-f9c7b206395d +res: sigqueue +DB::StorageSystemStackTrace::fillData(std::__1::vector::mutable_ptr, std::__1::allocator::mutable_ptr > >&, DB::Context const&, DB::SelectQueryInfo const&) const +DB::IStorageSystemOneBlock::read(std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&, DB::SelectQueryInfo const&, DB::Context const&, DB::QueryProcessingStage::Enum, unsigned long, unsigned int) +DB::InterpreterSelectQuery::executeFetchColumns(DB::QueryProcessingStage::Enum, DB::QueryPipeline&, std::__1::shared_ptr const&, std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&) +DB::InterpreterSelectQuery::executeImpl(DB::QueryPipeline&, std::__1::shared_ptr const&, std::__1::optional) +DB::InterpreterSelectQuery::execute() +DB::InterpreterSelectWithUnionQuery::execute() +DB::executeQueryImpl(char const*, char const*, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, DB::ReadBuffer*) +DB::executeQuery(std::__1::basic_string, std::__1::allocator > const&, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool) +DB::TCPHandler::runImpl() +DB::TCPHandler::run() +Poco::Net::TCPServerConnection::start() +Poco::Net::TCPServerDispatcher::run() +Poco::PooledThread::run() +Poco::ThreadImpl::runnableEntry(void*) +start_thread +__clone +``` + +Getting filenames and line numbers in ClickHouse source code: + +``` sql +WITH arrayMap(x -> addressToLine(x), trace) AS all, arrayFilter(x -> x LIKE '%/dbms/%', all) AS dbms SELECT thread_id, query_id, arrayStringConcat(notEmpty(dbms) ? dbms : all, '\n') AS res FROM system.stack_trace LIMIT 1 \G +``` + +``` text +Row 1: +────── +thread_id: 686 +query_id: cad353e7-1c29-4b2e-949f-93e597ab7a54 +res: /lib/x86_64-linux-gnu/libc-2.27.so +/build/obj-x86_64-linux-gnu/../src/Storages/System/StorageSystemStackTrace.cpp:182 +/build/obj-x86_64-linux-gnu/../contrib/libcxx/include/vector:656 +/build/obj-x86_64-linux-gnu/../src/Interpreters/InterpreterSelectQuery.cpp:1338 +/build/obj-x86_64-linux-gnu/../src/Interpreters/InterpreterSelectQuery.cpp:751 +/build/obj-x86_64-linux-gnu/../contrib/libcxx/include/optional:224 +/build/obj-x86_64-linux-gnu/../src/Interpreters/InterpreterSelectWithUnionQuery.cpp:192 +/build/obj-x86_64-linux-gnu/../src/Interpreters/executeQuery.cpp:384 +/build/obj-x86_64-linux-gnu/../src/Interpreters/executeQuery.cpp:643 +/build/obj-x86_64-linux-gnu/../src/Server/TCPHandler.cpp:251 +/build/obj-x86_64-linux-gnu/../src/Server/TCPHandler.cpp:1197 +/build/obj-x86_64-linux-gnu/../contrib/poco/Net/src/TCPServerConnection.cpp:57 +/build/obj-x86_64-linux-gnu/../contrib/libcxx/include/atomic:856 +/build/obj-x86_64-linux-gnu/../contrib/poco/Foundation/include/Poco/Mutex_POSIX.h:59 +/build/obj-x86_64-linux-gnu/../contrib/poco/Foundation/include/Poco/AutoPtr.h:223 +/lib/x86_64-linux-gnu/libpthread-2.27.so +/lib/x86_64-linux-gnu/libc-2.27.so +``` + +**See Also** + +- [Introspection Functions](../../sql-reference/functions/introspection.md) — Which introspection functions are available and how to use them. +- [system.trace_log](../system-tables/trace_log.md) — Contains stack traces collected by the sampling query profiler. +- [arrayMap](../../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-map) — Description and usage example of the `arrayMap` function. +- [arrayFilter](../../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-filter) — Description and usage example of the `arrayFilter` function. + + +[Original article](https://clickhouse.tech/docs/en/operations/system-tables/stack_trace) diff --git a/docs/ru/operations/system-tables.md b/docs/ru/operations/system-tables.md index b6b1dc3e35a..3eeee1e6621 100644 --- a/docs/ru/operations/system-tables.md +++ b/docs/ru/operations/system-tables.md @@ -983,7 +983,8 @@ ProfileEvents.Values: [1,97,81,5,81] - [system.query_log](#system_tables-query_log) — описание системной таблицы `query_log`, которая содержит общую информацию о выполненных запросах. -## system.trace\_log {#system_tables-trace_log} + +## system.trace_log {#system_tables-trace_log} Contains stack traces collected by the sampling query profiler. @@ -1029,6 +1030,93 @@ thread_number: 48 query_id: acc4d61f-5bd1-4a3e-bc91-2180be37c915 trace: [94222141367858,94222152240175,94222152325351,94222152329944,94222152330796,94222151449980,94222144088167,94222151682763,94222144088167,94222151682763,94222144088167,94222144058283,94222144059248,94222091840750,94222091842302,94222091831228,94222189631488,140509950166747,140509942945935] ``` +## system.stack_trace {#system-tables_stack_trace} + +Содержит трассировки стека всех серверных потоков. Позволяет разработчикам анализировать состояние сервера. + +Для анализа логов используйте [функции интроспекции](../sql-reference/functions/introspection.md): `addressToLine`, `addressToSymbol` и `demangle`. + +Столбцы: + +- `thread_id` ([UInt64](../sql-reference/data-types/int-uint.md)) — Идентификатор потока. +- `query_id` ([String](../sql-reference/data-types/string.md)) — Идентификатор запроса. Может быть использован для получения подробной информации о выполненном запросе из системной таблицы [query_log](#system_tables-query_log). +- `trace` ([Array(UInt64)](../sql-reference/data-types/array.md)) — [Трассировка стека](https://en.wikipedia.org/wiki/Stack_trace). Представляет собой список физических адресов, по которым расположены вызываемые методы. + +**Пример** + +Включение функций интроспекции: + +``` sql +SET allow_introspection_functions = 1; +``` + +Получение символов из объектных файлов ClickHouse: + +``` sql +WITH arrayMap(x -> demangle(addressToSymbol(x)), trace) AS all SELECT thread_id, query_id, arrayStringConcat(all, '\n') AS res FROM system.stack_trace LIMIT 1 \G +``` + +``` text +Row 1: +────── +thread_id: 686 +query_id: 1a11f70b-626d-47c1-b948-f9c7b206395d +res: sigqueue +DB::StorageSystemStackTrace::fillData(std::__1::vector::mutable_ptr, std::__1::allocator::mutable_ptr > >&, DB::Context const&, DB::SelectQueryInfo const&) const +DB::IStorageSystemOneBlock::read(std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&, DB::SelectQueryInfo const&, DB::Context const&, DB::QueryProcessingStage::Enum, unsigned long, unsigned int) +DB::InterpreterSelectQuery::executeFetchColumns(DB::QueryProcessingStage::Enum, DB::QueryPipeline&, std::__1::shared_ptr const&, std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&) +DB::InterpreterSelectQuery::executeImpl(DB::QueryPipeline&, std::__1::shared_ptr const&, std::__1::optional) +DB::InterpreterSelectQuery::execute() +DB::InterpreterSelectWithUnionQuery::execute() +DB::executeQueryImpl(char const*, char const*, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, DB::ReadBuffer*) +DB::executeQuery(std::__1::basic_string, std::__1::allocator > const&, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool) +DB::TCPHandler::runImpl() +DB::TCPHandler::run() +Poco::Net::TCPServerConnection::start() +Poco::Net::TCPServerDispatcher::run() +Poco::PooledThread::run() +Poco::ThreadImpl::runnableEntry(void*) +start_thread +__clone +``` + +Получение имен файлов и номеров строк в исходном коде ClickHouse: + +``` sql +WITH arrayMap(x -> addressToLine(x), trace) AS all, arrayFilter(x -> x LIKE '%/dbms/%', all) AS dbms SELECT thread_id, query_id, arrayStringConcat(notEmpty(dbms) ? dbms : all, '\n') AS res FROM system.stack_trace LIMIT 1 \G +``` + +``` text +Row 1: +────── +thread_id: 686 +query_id: cad353e7-1c29-4b2e-949f-93e597ab7a54 +res: /lib/x86_64-linux-gnu/libc-2.27.so +/build/obj-x86_64-linux-gnu/../src/Storages/System/StorageSystemStackTrace.cpp:182 +/build/obj-x86_64-linux-gnu/../contrib/libcxx/include/vector:656 +/build/obj-x86_64-linux-gnu/../src/Interpreters/InterpreterSelectQuery.cpp:1338 +/build/obj-x86_64-linux-gnu/../src/Interpreters/InterpreterSelectQuery.cpp:751 +/build/obj-x86_64-linux-gnu/../contrib/libcxx/include/optional:224 +/build/obj-x86_64-linux-gnu/../src/Interpreters/InterpreterSelectWithUnionQuery.cpp:192 +/build/obj-x86_64-linux-gnu/../src/Interpreters/executeQuery.cpp:384 +/build/obj-x86_64-linux-gnu/../src/Interpreters/executeQuery.cpp:643 +/build/obj-x86_64-linux-gnu/../src/Server/TCPHandler.cpp:251 +/build/obj-x86_64-linux-gnu/../src/Server/TCPHandler.cpp:1197 +/build/obj-x86_64-linux-gnu/../contrib/poco/Net/src/TCPServerConnection.cpp:57 +/build/obj-x86_64-linux-gnu/../contrib/libcxx/include/atomic:856 +/build/obj-x86_64-linux-gnu/../contrib/poco/Foundation/include/Poco/Mutex_POSIX.h:59 +/build/obj-x86_64-linux-gnu/../contrib/poco/Foundation/include/Poco/AutoPtr.h:223 +/lib/x86_64-linux-gnu/libpthread-2.27.so +/lib/x86_64-linux-gnu/libc-2.27.so +``` + +**См. также** + +- [Функции интроспекции](../sql-reference/functions/introspection.md) — Что такое функции интроспекции и как их использовать. +- [system.trace_log](system-tables.md#system_tables-trace_log) — Содержит трассировки стека, собранные профилировщиком выборочных запросов. +- [arrayMap](../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-map) — Описание и пример использования функции `arrayMap`. +- [arrayFilter](../sql-reference/functions/higher-order-functions.md#higher_order_functions-array-filter) — Описание и пример использования функции `arrayFilter`. + ## system.replicas {#system_tables-replicas} diff --git a/docs/ru/sql-reference/functions/geo/index.md b/docs/ru/sql-reference/functions/geo/index.md index 5e2ebd44718..bfea32a245b 100644 --- a/docs/ru/sql-reference/functions/geo/index.md +++ b/docs/ru/sql-reference/functions/geo/index.md @@ -1,7 +1,7 @@ --- toc_priority: 62 -toc_folder_title: hidden -toc_title: Функции для работы с географическими координатами +toc_folder_title: Гео-данные +toc_title: hidden --- diff --git a/docs/ru/sql-reference/statements/grant.md b/docs/ru/sql-reference/statements/grant.md index ffc58d09d95..279b094247b 100644 --- a/docs/ru/sql-reference/statements/grant.md +++ b/docs/ru/sql-reference/statements/grant.md @@ -1,474 +1,479 @@ ---- -toc_priority: 39 -toc_title: GRANT ---- +# GRANT -# GRANT {#grant} +- Присваивает [привилегии](#grant-privileges) пользователям или ролям ClickHouse. +- Назначает роли пользователям или другим ролям. -- Grants [privileges](#grant-privileges) to ClickHouse user accounts or roles. -- Assigns roles to user accounts or to the other roles. +Отозвать привилегию можно с помощью выражения [REVOKE](revoke.md). Чтобы вывести список присвоенных привилегий, воспользуйтесь выражением [SHOW GRANTS](show.md#show-grants-statement). -To revoke privileges, use the [REVOKE](../../sql-reference/statements/revoke.md) statement. Also you can list granted privileges with the [SHOW GRANTS](../../sql-reference/statements/show.md#show-grants-statement) statement. +## Синтаксис присвоения привилегий {#grant-privigele-syntax} -## Granting Privilege Syntax {#grant-privigele-syntax} - -``` sql +```sql GRANT [ON CLUSTER cluster_name] privilege[(column_name [,...])] [,...] ON {db.table|db.*|*.*|table|*} TO {user | role | CURRENT_USER} [,...] [WITH GRANT OPTION] ``` -- `privilege` — Type of privilege. -- `role` — ClickHouse user role. -- `user` — ClickHouse user account. +- `privilege` — Тип привилегии +- `role` — Роль пользователя ClickHouse. +- `user` — Пользователь ClickHouse. -The `WITH GRANT OPTION` clause grants `user` or `role` with permission to execute the `GRANT` query. Users can grant privileges of the same scope they have and less. +`WITH GRANT OPTION` разрешает пользователю или роли выполнять запрос `GRANT`. Пользователь может выдавать только те привилегии, которые есть у него, той же или меньшей области действий. -## Assigning Role Syntax {#assign-role-syntax} -``` sql +## Синтаксис назначения ролей {#assign-role-syntax} + +```sql GRANT [ON CLUSTER cluster_name] role [,...] TO {user | another_role | CURRENT_USER} [,...] [WITH ADMIN OPTION] ``` -- `role` — ClickHouse user role. -- `user` — ClickHouse user account. +- `role` — Роль пользователя ClickHouse. +- `user` — Пользователь ClickHouse. -The `WITH ADMIN OPTION` clause grants [ADMIN OPTION](#admin-option-privilege) privilege to `user` or `role`. +`WITH ADMIN OPTION` присваивает привилегию [ADMIN OPTION](#admin-option-privilege) пользователю или роли. -## Usage {#grant-usage} +## Использование {#grant-usage} -To use `GRANT`, your account must have the `GRANT OPTION` privilege. You can grant privileges only inside the scope of your account privileges. +Для использования `GRANT` пользователь должен иметь привилегию `GRANT OPTION`. Пользователь может выдавать привилегии только внутри области действий назначенных ему самому привилегий. -For example, administrator has granted privileges to the `john` account by the query: +Например, администратор выдал привилегию пользователю `john`: -``` sql +```sql GRANT SELECT(x,y) ON db.table TO john WITH GRANT OPTION ``` -It means that `john` has the permission to execute: +Это означает, что пользователю `john` разрешено выполнять: -- `SELECT x,y FROM db.table`. -- `SELECT x FROM db.table`. -- `SELECT y FROM db.table`. +- `SELECT x,y FROM db.table`. +- `SELECT x FROM db.table`. +- `SELECT y FROM db.table`. -`john` can’t execute `SELECT z FROM db.table`. The `SELECT * FROM db.table` also is not available. Processing this query, ClickHouse doesn’t return any data, even `x` and `y`. The only exception is if a table contains only `x` and `y` columns. In this case ClickHouse returns all the data. +`john` не может выполнить `SELECT z FROM db.table` или `SELECT * FROM db.table`. После обработки данных запросов ClickHouse ничего не вернет — даже `x` или `y`. Единственное исключение — если таблица содержит только столбцы `x` и `y`. В таком случае ClickHouse вернет все данные. -Also `john` has the `GRANT OPTION` privilege, so it can grant other users with privileges of the same or smaller scope. +Также у `john` есть привилегия `GRANT OPTION`. `john` может выдать другим пользователям привилегии той же или меньшей области действий из тех, которые есть у него. -Specifying privileges you can use asterisk (`*`) instead of a table or a database name. For example, the `GRANT SELECT ON db.* TO john` query allows `john` to execute the `SELECT` query over all the tables in `db` database. Also, you can omit database name. In this case privileges are granted for current database. For example, `GRANT SELECT ON * TO john` grants the privilege on all the tables in the current database, `GRANT SELECT ON mytable TO john` grants the privilege on the `mytable` table in the current database. +При присвоении привилегий допускается использовать астериск (`*`) вместо имени таблицы или базы данных. Например, запрос `GRANT SELECT ON db.* TO john` позволит пользователю `john` выполнять `SELECT` над всеми таблицам в базе данных `db`. Также вы можете опускать имя базы данных. В таком случае привилегии позволят совершать операции над текущей базой данных. Например, запрос `GRANT SELECT ON * TO john` выдаст привилегию на выполнение `SELECT` над всеми таблицами в текущей базе данных; `GRANT SELECT ON mytable TO john` — только над таблицей `mytable` в текущей базе данных. -Access to the `system` database is always allowed (since this database is used for processing queries). +Доступ к базе данных `system` разрешен всегда (данная база данных используется при обработке запросов). -You can grant multiple privileges to multiple accounts in one query. The query `GRANT SELECT, INSERT ON *.* TO john, robin` allows accounts `john` and `robin` to execute the `INSERT` and `SELECT` queries over all the tables in all the databases on the server. +Вы можете присвоить несколько привилегий нескольким пользователям в одном запросе. Запрос `GRANT SELECT, INSERT ON *.* TO john, robin` позволит пользователям `john` и `robin` выполнять `INSERT` и `SELECT` над всеми таблицами всех баз данных на сервере. -## Privileges {#grant-privileges} -Privilege is a permission to execute specific kind of queries. +## Привилегии {#grant-privileges} -Privileges have a hierarchical structure. A set of permitted queries depends on the privilege scope. +Привилегия — это разрешение на выполнение определенного типа запросов. -Hierarchy of privileges: +Привилегии имеют иерархическую структуру. Набор разрешенных запросов зависит от области действия привилегии. -- [SELECT](#grant-select) -- [INSERT](#grant-insert) -- [ALTER](#grant-alter) - - `ALTER TABLE` - - `ALTER UPDATE` - - `ALTER DELETE` - - `ALTER COLUMN` - - `ALTER ADD COLUMN` - - `ALTER DROP COLUMN` - - `ALTER MODIFY COLUMN` - - `ALTER COMMENT COLUMN` - - `ALTER CLEAR COLUMN` - - `ALTER RENAME COLUMN` - - `ALTER INDEX` - - `ALTER ORDER BY` - - `ALTER ADD INDEX` - - `ALTER DROP INDEX` - - `ALTER MATERIALIZE INDEX` - - `ALTER CLEAR INDEX` - - `ALTER CONSTRAINT` - - `ALTER ADD CONSTRAINT` - - `ALTER DROP CONSTRAINT` - - `ALTER TTL` - - `ALTER MATERIALIZE TTL` - - `ALTER SETTINGS` - - `ALTER MOVE PARTITION` - - `ALTER FETCH PARTITION` - - `ALTER FREEZE PARTITION` - - `ALTER VIEW` - - `ALTER VIEW REFRESH` - - `ALTER VIEW MODIFY QUERY` -- [CREATE](#grant-create) - - `CREATE DATABASE` - - `CREATE TABLE` - - `CREATE VIEW` - - `CREATE DICTIONARY` - - `CREATE TEMPORARY TABLE` -- [DROP](#grant-drop) - - `DROP DATABASE` - - `DROP TABLE` - - `DROP VIEW` - - `DROP DICTIONARY` -- [TRUNCATE](#grant-truncate) -- [OPTIMIZE](#grant-optimize) -- [SHOW](#grant-show) - - `SHOW DATABASES` - - `SHOW TABLES` - - `SHOW COLUMNS` - - `SHOW DICTIONARIES` -- [KILL QUERY](#grant-kill-query) -- [ACCESS MANAGEMENT](#grant-access-management) - - `CREATE USER` - - `ALTER USER` - - `DROP USER` - - `CREATE ROLE` - - `ALTER ROLE` - - `DROP ROLE` - - `CREATE ROW POLICY` - - `ALTER ROW POLICY` - - `DROP ROW POLICY` - - `CREATE QUOTA` - - `ALTER QUOTA` - - `DROP QUOTA` - - `CREATE SETTINGS PROFILE` - - `ALTER SETTINGS PROFILE` - - `DROP SETTINGS PROFILE` - - `SHOW ACCESS` - - `SHOW_USERS` - - `SHOW_ROLES` - - `SHOW_ROW_POLICIES` - - `SHOW_QUOTAS` - - `SHOW_SETTINGS_PROFILES` - - `ROLE ADMIN` -- [SYSTEM](#grant-system) - - `SYSTEM SHUTDOWN` - - `SYSTEM DROP CACHE` - - `SYSTEM DROP DNS CACHE` - - `SYSTEM DROP MARK CACHE` - - `SYSTEM DROP UNCOMPRESSED CACHE` - - `SYSTEM RELOAD` - - `SYSTEM RELOAD CONFIG` - - `SYSTEM RELOAD DICTIONARY` - - `SYSTEM RELOAD EMBEDDED DICTIONARIES` - - `SYSTEM MERGES` - - `SYSTEM TTL MERGES` - - `SYSTEM FETCHES` - - `SYSTEM MOVES` - - `SYSTEM SENDS` - - `SYSTEM DISTRIBUTED SENDS` - - `SYSTEM REPLICATED SENDS` - - `SYSTEM REPLICATION QUEUES` - - `SYSTEM SYNC REPLICA` - - `SYSTEM RESTART REPLICA` - - `SYSTEM FLUSH` - - `SYSTEM FLUSH DISTRIBUTED` - - `SYSTEM FLUSH LOGS` -- [INTROSPECTION](#grant-introspection) - - `addressToLine` - - `addressToSymbol` - - `demangle` -- [SOURCES](#grant-sources) - - `FILE` - - `URL` - - `REMOTE` - - `YSQL` - - `ODBC` - - `JDBC` - - `HDFS` - - `S3` -- [dictGet](#grant-dictget) +Иерархия привилегий: -Examples of how this hierarchy is treated: +- [SELECT](#grant-select) +- [INSERT](#grant-insert) +- [ALTER](#grant-alter) + - `ALTER TABLE` + - `ALTER UPDATE` + - `ALTER DELETE` + - `ALTER COLUMN` + - `ALTER ADD COLUMN` + - `ALTER DROP COLUMN` + - `ALTER MODIFY COLUMN` + - `ALTER COMMENT COLUMN` + - `ALTER CLEAR COLUMN` + - `ALTER RENAME COLUMN` + - `ALTER INDEX` + - `ALTER ORDER BY` + - `ALTER ADD INDEX` + - `ALTER DROP INDEX` + - `ALTER MATERIALIZE INDEX` + - `ALTER CLEAR INDEX` + - `ALTER CONSTRAINT` + - `ALTER ADD CONSTRAINT` + - `ALTER DROP CONSTRAINT` + - `ALTER TTL` + - `ALTER MATERIALIZE TTL` + - `ALTER SETTINGS` + - `ALTER MOVE PARTITION` + - `ALTER FETCH PARTITION` + - `ALTER FREEZE PARTITION` + - `ALTER VIEW` + - `ALTER VIEW REFRESH ` + - `ALTER VIEW MODIFY QUERY` +- [CREATE](#grant-create) + - `CREATE DATABASE` + - `CREATE TABLE` + - `CREATE VIEW` + - `CREATE DICTIONARY` + - `CREATE TEMPORARY TABLE` +- [DROP](#grant-drop) + - `DROP DATABASE` + - `DROP TABLE` + - `DROP VIEW` + - `DROP DICTIONARY` +- [TRUNCATE](#grant-truncate) +- [OPTIMIZE](#grant-optimize) +- [SHOW](#grant-show) + - `SHOW DATABASES` + - `SHOW TABLES` + - `SHOW COLUMNS` + - `SHOW DICTIONARIES` +- [KILL QUERY](#grant-kill-query) +- [ACCESS MANAGEMENT](#grant-access-management) + - `CREATE USER` + - `ALTER USER` + - `DROP USER` + - `CREATE ROLE` + - `ALTER ROLE` + - `DROP ROLE` + - `CREATE ROW POLICY` + - `ALTER ROW POLICY` + - `DROP ROW POLICY` + - `CREATE QUOTA` + - `ALTER QUOTA` + - `DROP QUOTA` + - `CREATE SETTINGS PROFILE` + - `ALTER SETTINGS PROFILE` + - `DROP SETTINGS PROFILE` + - `SHOW ACCESS` + - `SHOW_USERS` + - `SHOW_ROLES` + - `SHOW_ROW_POLICIES` + - `SHOW_QUOTAS` + - `SHOW_SETTINGS_PROFILES` + - `ROLE ADMIN` +- [SYSTEM](#grant-system) + - `SYSTEM SHUTDOWN` + - `SYSTEM DROP CACHE` + - `SYSTEM DROP DNS CACHE` + - `SYSTEM DROP MARK CACHE` + - `SYSTEM DROP UNCOMPRESSED CACHE` + - `SYSTEM RELOAD` + - `SYSTEM RELOAD CONFIG` + - `SYSTEM RELOAD DICTIONARY` + - `SYSTEM RELOAD EMBEDDED DICTIONARIES` + - `SYSTEM MERGES` + - `SYSTEM TTL MERGES` + - `SYSTEM FETCHES` + - `SYSTEM MOVES` + - `SYSTEM SENDS` + - `SYSTEM DISTRIBUTED SENDS` + - `SYSTEM REPLICATED SENDS` + - `SYSTEM REPLICATION QUEUES` + - `SYSTEM SYNC REPLICA` + - `SYSTEM RESTART REPLICA` + - `SYSTEM FLUSH` + - `SYSTEM FLUSH DISTRIBUTED` + - `SYSTEM FLUSH LOGS` +- [INTROSPECTION](#grant-introspection) + - `addressToLine` + - `addressToSymbol` + - `demangle` +- [SOURCES](#grant-sources) + - `FILE` + - `URL` + - `REMOTE` + - `MYSQL` + - `ODBC` + - `JDBC` + - `HDFS` + - `S3` +- [dictGet](#grant-dictget) -- The `ALTER` privilege includes all other `ALTER*` privileges. -- `ALTER CONSTRAINT` includes `ALTER ADD CONSTRAINT` and `ALTER DROP CONSTRAINT` privileges. +Примеры того, как трактуется данная иерархия: -Privileges are applied at different levels. Knowing of a level suggests syntax available for privilege. +- Привилегия `ALTER` включает все остальные `ALTER*` привилегии. +- `ALTER CONSTRAINT` включает `ALTER ADD CONSTRAINT` и `ALTER DROP CONSTRAINT`. -Levels (from lower to higher): +Привилегии применяются на разных уровнях. Уровень определяет синтаксис присваивания привилегии. -- `COLUMN` — Privilege can be granted for column, table, database, or globally. -- `TABLE` — Privilege can be granted for table, database, or globally. -- `VIEW` — Privilege can be granted for view, database, or globally. -- `DICTIONARY` — Privilege can be granted for dictionary, database, or globally. -- `DATABASE` — Privilege can be granted for database or globally. -- `GLOBAL` — Privilege can be granted only globally. -- `GROUP` — Groups privileges of different levels. When `GROUP`-level privilege is granted, only that privileges from the group are granted which correspond to the used syntax. +Уровни (от низшего к высшему): -Examples of allowed syntax: +- `COLUMN` — Привилегия присваивается для столбца, таблицы, базы данных или глобально. +- `TABLE` — Привилегия присваивается для таблицы, базы данных или глобально. +- `VIEW` — Привилегия присваивается для представления, базы данных или глобально. +- `DICTIONARY` — Привилегия присваивается для словаря, базы данных или глобально. +- `DATABASE` — Привилегия присваивается для базы данных или глобально. +- `GLOBAL` — Привилегия присваивается только глобально. +- `GROUP` — Группирует привилегии разных уровней. При присвоении привилегии уровня `GROUP` присваиваются только привилегии из группы в соответствии с используемым синтаксисом. -- `GRANT SELECT(x) ON db.table TO user` -- `GRANT SELECT ON db.* TO user` +Примеры допустимого синтаксиса: -Examples of disallowed syntax: +- `GRANT SELECT(x) ON db.table TO user` +- `GRANT SELECT ON db.* TO user` -- `GRANT CREATE USER(x) ON db.table TO user` -- `GRANT CREATE USER ON db.* TO user` +Примеры недопустимого синтаксиса: -The special privilege [ALL](#grant-all) grants all the privileges to a user account or a role. +- `GRANT CREATE USER(x) ON db.table TO user` +- `GRANT CREATE USER ON db.* TO user` -By default, a user account or a role has no privileges. +Специальная привилегия [ALL](#grant-all) присваивает все привилегии пользователю или роли. -If a user or a role has no privileges, it is displayed as [NONE](#grant-none) privilege. +По умолчанию пользователь или роль не имеют привилегий. + +Отсутствие привилегий у пользователя или роли отображается как привилегия [NONE](#grant-none). + +Выполнение некоторых запросов требует определенного набора привилегий. Например, чтобы выполнить запрос [RENAME](misc.md#misc_operations-rename), нужны следующие привилегии: `SELECT`, `CREATE TABLE`, `INSERT` и `DROP TABLE`. -Some queries by their implementation require a set of privileges. For example, to execute the [RENAME](../../sql-reference/statements/misc.md#misc_operations-rename) query you need the following privileges: `SELECT`, `CREATE TABLE`, `INSERT` and `DROP TABLE`. ### SELECT {#grant-select} -Allows executing [SELECT](../../sql-reference/statements/select/index.md) queries. +Разрешает выполнять запросы [SELECT](select/index.md). -Privilege level: `COLUMN`. +Уровень: `COLUMN`. -**Description** +**Описание** -User granted with this privilege can execute `SELECT` queries over a specified list of columns in the specified table and database. If user includes other columns then specified a query returns no data. +Пользователь с данной привилегией может выполнять запросы `SELECT` над определенными столбцами из определенной таблицы и базы данных. При включении в запрос других столбцов запрос ничего не вернет. -Consider the following privilege: +Рассмотрим следующую привилегию: -``` sql +```sql GRANT SELECT(x,y) ON db.table TO john ``` -This privilege allows `john` to execute any `SELECT` query that involves data from the `x` and/or `y` columns in `db.table`, for example, `SELECT x FROM db.table`. `john` can’t execute `SELECT z FROM db.table`. The `SELECT * FROM db.table` also is not available. Processing this query, ClickHouse doesn’t return any data, even `x` and `y`. The only exception is if a table contains only `x` and `y` columns, in this case ClickHouse returns all the data. +Данная привилегия позволяет пользователю `john` выполнять выборку данных из столбцов `x` и/или `y` в `db.table`, например, `SELECT x FROM db.table`. `john` не может выполнить `SELECT z FROM db.table` или `SELECT * FROM db.table`. После обработки данных запросов ClickHouse ничего не вернет — даже `x` или `y`. Единственное исключение — если таблица содержит только столбцы `x` и `y`. В таком случае ClickHouse вернет все данные. ### INSERT {#grant-insert} -Allows executing [INSERT](../../sql-reference/statements/insert-into.md) queries. +Разрешает выполнять запросы [INSERT](insert-into.md). -Privilege level: `COLUMN`. +Уровень: `COLUMN`. -**Description** +**Описание** -User granted with this privilege can execute `INSERT` queries over a specified list of columns in the specified table and database. If user includes other columns then specified a query doesn’t insert any data. +Пользователь с данной привилегией может выполнять запросы `INSERT` над определенными столбцами из определенной таблицы и базы данных. При включении в запрос других столбцов запрос не добавит никаких данных. -**Example** +**Пример** -``` sql +```sql GRANT INSERT(x,y) ON db.table TO john ``` -The granted privilege allows `john` to insert data to the `x` and/or `y` columns in `db.table`. +Присвоенная привилегия позволит пользователю `john` вставить данные в столбцы `x` и/или `y` в `db.table`. ### ALTER {#grant-alter} -Allows executing [ALTER](../../sql-reference/statements/alter.md) queries according to the following hierarchy of privileges: +Разрешает выполнять запросы [ALTER](alter.md) в соответствии со следующей иерархией привилегий: -- `ALTER`. Level: `COLUMN`. - - `ALTER TABLE`. Level: `GROUP` - - `ALTER UPDATE`. Level: `COLUMN`. Aliases: `UPDATE` - - `ALTER DELETE`. Level: `COLUMN`. Aliases: `DELETE` - - `ALTER COLUMN`. Level: `GROUP` - - `ALTER ADD COLUMN`. Level: `COLUMN`. Aliases: `ADD COLUMN` - - `ALTER DROP COLUMN`. Level: `COLUMN`. Aliases: `DROP COLUMN` - - `ALTER MODIFY COLUMN`. Level: `COLUMN`. Aliases: `MODIFY COLUMN` - - `ALTER COMMENT COLUMN`. Level: `COLUMN`. Aliases: `COMMENT COLUMN` - - `ALTER CLEAR COLUMN`. Level: `COLUMN`. Aliases: `CLEAR COLUMN` - - `ALTER RENAME COLUMN`. Level: `COLUMN`. Aliases: `RENAME COLUMN` - - `ALTER INDEX`. Level: `GROUP`. Aliases: `INDEX` - - `ALTER ORDER BY`. Level: `TABLE`. Aliases: `ALTER MODIFY ORDER BY`, `MODIFY ORDER BY` - - `ALTER ADD INDEX`. Level: `TABLE`. Aliases: `ADD INDEX` - - `ALTER DROP INDEX`. Level: `TABLE`. Aliases: `DROP INDEX` - - `ALTER MATERIALIZE INDEX`. Level: `TABLE`. Aliases: `MATERIALIZE INDEX` - - `ALTER CLEAR INDEX`. Level: `TABLE`. Aliases: `CLEAR INDEX` - - `ALTER CONSTRAINT`. Level: `GROUP`. Aliases: `CONSTRAINT` - - `ALTER ADD CONSTRAINT`. Level: `TABLE`. Aliases: `ADD CONSTRAINT` - - `ALTER DROP CONSTRAINT`. Level: `TABLE`. Aliases: `DROP CONSTRAINT` - - `ALTER TTL`. Level: `TABLE`. Aliases: `ALTER MODIFY TTL`, `MODIFY TTL` - - `ALTER MATERIALIZE TTL`. Level: `TABLE`. Aliases: `MATERIALIZE TTL` - - `ALTER SETTINGS`. Level: `TABLE`. Aliases: `ALTER SETTING`, `ALTER MODIFY SETTING`, `MODIFY SETTING` - - `ALTER MOVE PARTITION`. Level: `TABLE`. Aliases: `ALTER MOVE PART`, `MOVE PARTITION`, `MOVE PART` - - `ALTER FETCH PARTITION`. Level: `TABLE`. Aliases: `FETCH PARTITION` - - `ALTER FREEZE PARTITION`. Level: `TABLE`. Aliases: `FREEZE PARTITION` - - `ALTER VIEW` Level: `GROUP` - - `ALTER VIEW REFRESH`. Level: `VIEW`. Aliases: `ALTER LIVE VIEW REFRESH`, `REFRESH VIEW` - - `ALTER VIEW MODIFY QUERY`. Level: `VIEW`. Aliases: `ALTER TABLE MODIFY QUERY` +- `ALTER`. Уровень: `COLUMN`. + - `ALTER TABLE`. Уровень: `GROUP` + - `ALTER UPDATE`. Уровень: `COLUMN`. Алиасы: `UPDATE` + - `ALTER DELETE`. Уровень: `COLUMN`. Алиасы: `DELETE` + - `ALTER COLUMN`. Уровень: `GROUP` + - `ALTER ADD COLUMN`. Уровень: `COLUMN`. Алиасы: `ADD COLUMN` + - `ALTER DROP COLUMN`. Уровень: `COLUMN`. Алиасы: `DROP COLUMN` + - `ALTER MODIFY COLUMN`. Уровень: `COLUMN`. Алиасы: `MODIFY COLUMN` + - `ALTER COMMENT COLUMN`. Уровень: `COLUMN`. Алиасы: `COMMENT COLUMN` + - `ALTER CLEAR COLUMN`. Уровень: `COLUMN`. Алиасы: `CLEAR COLUMN` + - `ALTER RENAME COLUMN`. Уровень: `COLUMN`. Алиасы: `RENAME COLUMN` + - `ALTER INDEX`. Уровень: `GROUP`. Алиасы: `INDEX` + - `ALTER ORDER BY`. Уровень: `TABLE`. Алиасы: `ALTER MODIFY ORDER BY`, `MODIFY ORDER BY` + - `ALTER ADD INDEX`. Уровень: `TABLE`. Алиасы: `ADD INDEX` + - `ALTER DROP INDEX`. Уровень: `TABLE`. Алиасы: `DROP INDEX` + - `ALTER MATERIALIZE INDEX`. Уровень: `TABLE`. Алиасы: `MATERIALIZE INDEX` + - `ALTER CLEAR INDEX`. Уровень: `TABLE`. Алиасы: `CLEAR INDEX` + - `ALTER CONSTRAINT`. Уровень: `GROUP`. Алиасы: `CONSTRAINT` + - `ALTER ADD CONSTRAINT`. Уровень: `TABLE`. Алиасы: `ADD CONSTRAINT` + - `ALTER DROP CONSTRAINT`. Уровень: `TABLE`. Алиасы: `DROP CONSTRAINT` + - `ALTER TTL`. Уровень: `TABLE`. Алиасы: `ALTER MODIFY TTL`, `MODIFY TTL` + - `ALTER MATERIALIZE TTL`. Уровень: `TABLE`. Алиасы: `MATERIALIZE TTL` + - `ALTER SETTINGS`. Уровень: `TABLE`. Алиасы: `ALTER SETTING`, `ALTER MODIFY SETTING`, `MODIFY SETTING` + - `ALTER MOVE PARTITION`. Уровень: `TABLE`. Алиасы: `ALTER MOVE PART`, `MOVE PARTITION`, `MOVE PART` + - `ALTER FETCH PARTITION`. Уровень: `TABLE`. Алиасы: `FETCH PARTITION` + - `ALTER FREEZE PARTITION`. Уровень: `TABLE`. Алиасы: `FREEZE PARTITION` + - `ALTER VIEW` Уровень: `GROUP` + - `ALTER VIEW REFRESH `. Уровень: `VIEW`. Алиасы: `ALTER LIVE VIEW REFRESH`, `REFRESH VIEW` + - `ALTER VIEW MODIFY QUERY`. Уровень: `VIEW`. Алиасы: `ALTER TABLE MODIFY QUERY` -Examples of how this hierarchy is treated: +Примеры того, как трактуется данная иерархия: -- The `ALTER` privilege includes all other `ALTER*` privileges. -- `ALTER CONSTRAINT` includes `ALTER ADD CONSTRAINT` and `ALTER DROP CONSTRAINT` privileges. +- Привилегия `ALTER` включает все остальные `ALTER*` привилегии. +- `ALTER CONSTRAINT` включает `ALTER ADD CONSTRAINT` и `ALTER DROP CONSTRAINT`. -**Notes** +**Дополнительно** -- The `MODIFY SETTING` privilege allows modifying table engine settings. It doesn’t affect settings or server configuration parameters. -- The `ATTACH` operation needs the [CREATE](#grant-create) privilege. -- The `DETACH` operation needs the [DROP](#grant-drop) privilege. -- To stop mutation by the [KILL MUTATION](../../sql-reference/statements/misc.md#kill-mutation-statement) query, you need to have a privilege to start this mutation. For example, if you want to stop the `ALTER UPDATE` query, you need the `ALTER UPDATE`, `ALTER TABLE`, or `ALTER` privilege. +- Привилегия `MODIFY SETTING` позволяет изменять настройки движков таблиц. Не влияет на настройки или конфигурационные параметры сервера. +- Операция `ATTACH` требует наличие привилегии [CREATE](#grant-create). +- Операция `DETACH` требует наличие привилегии [DROP](#grant-drop). +- Для остановки мутации с помощью [KILL MUTATION](misc.md#kill-mutation-statement), необходима привилегия на выполнение данной мутации. Например, чтобы остановить запрос `ALTER UPDATE`, необходима одна из привилегий: `ALTER UPDATE`, `ALTER TABLE` или `ALTER`. ### CREATE {#grant-create} -Allows executing [CREATE](../../sql-reference/statements/create.md) and [ATTACH](../../sql-reference/statements/misc.md#attach) DDL-queries according to the following hierarchy of privileges: +Разрешает выполнять DDL-запросы [CREATE](create.md) и [ATTACH](misc.md#attach) в соответствии со следующей иерархией привилегий: -- `CREATE`. Level: `GROUP` - - `CREATE DATABASE`. Level: `DATABASE` - - `CREATE TABLE`. Level: `TABLE` - - `CREATE VIEW`. Level: `VIEW` - - `CREATE DICTIONARY`. Level: `DICTIONARY` - - `CREATE TEMPORARY TABLE`. Level: `GLOBAL` +- `CREATE`. Уровень: `GROUP` + - `CREATE DATABASE`. Уровень: `DATABASE` + - `CREATE TABLE`. Уровень: `TABLE` + - `CREATE VIEW`. Уровень: `VIEW` + - `CREATE DICTIONARY`. Уровень: `DICTIONARY` + - `CREATE TEMPORARY TABLE`. Уровень: `GLOBAL` -**Notes** +**Дополнительно** -- To delete the created table, a user needs [DROP](#grant-drop). +- Для удаления созданной таблицы пользователю необходима привилегия [DROP](#grant-drop). ### DROP {#grant-drop} -Allows executing [DROP](../../sql-reference/statements/misc.md#drop) and [DETACH](../../sql-reference/statements/misc.md#detach-statement) queries according to the following hierarchy of privileges: +Разрешает выполнять запросы [DROP](misc.md#drop) и [DETACH](misc.md#detach-statement) в соответствии со следующей иерархией привилегий: + +- `DROP`. Уровень: + - `DROP DATABASE`. Уровень: `DATABASE` + - `DROP TABLE`. Уровень: `TABLE` + - `DROP VIEW`. Уровень: `VIEW` + - `DROP DICTIONARY`. Уровень: `DICTIONARY` -- `DROP`. Level: - - `DROP DATABASE`. Level: `DATABASE` - - `DROP TABLE`. Level: `TABLE` - - `DROP VIEW`. Level: `VIEW` - - `DROP DICTIONARY`. Level: `DICTIONARY` ### TRUNCATE {#grant-truncate} -Allows executing [TRUNCATE](../../sql-reference/statements/misc.md#truncate-statement) queries. +Разрешает выполнять запросы [TRUNCATE](misc.md#truncate-statement). -Privilege level: `TABLE`. +Уровень: `TABLE`. ### OPTIMIZE {#grant-optimize} -Allows executing [OPTIMIZE TABLE](../../sql-reference/statements/misc.md#misc_operations-optimize) queries. +Разрешает выполнять запросы [OPTIMIZE TABLE](misc.md#misc_operations-optimize). -Privilege level: `TABLE`. +Уровень: `TABLE`. ### SHOW {#grant-show} -Allows executing `SHOW`, `DESCRIBE`, `USE`, and `EXISTS` queries according to the following hierarchy of privileges: +Разрешает выполнять запросы `SHOW`, `DESCRIBE`, `USE` и `EXISTS` в соответствии со следующей иерархией привилегий: -- `SHOW`. Level: `GROUP` - - `SHOW DATABASES`. Level: `DATABASE`. Allows to execute `SHOW DATABASES`, `SHOW CREATE DATABASE`, `USE ` queries. - - `SHOW TABLES`. Level: `TABLE`. Allows to execute `SHOW TABLES`, `EXISTS `, `CHECK
` queries. - - `SHOW COLUMNS`. Level: `COLUMN`. Allows to execute `SHOW CREATE TABLE`, `DESCRIBE` queries. - - `SHOW DICTIONARIES`. Level: `DICTIONARY`. Allows to execute `SHOW DICTIONARIES`, `SHOW CREATE DICTIONARY`, `EXISTS ` queries. +- `SHOW`. Уровень: `GROUP` + - `SHOW DATABASES`. Уровень: `DATABASE`. Разрешает выполнять запросы `SHOW DATABASES`, `SHOW CREATE DATABASE`, `USE `. + - `SHOW TABLES`. Уровень: `TABLE`. Разрешает выполнять запросы `SHOW TABLES`, `EXISTS
`, `CHECK
`. + - `SHOW COLUMNS`. Уровень: `COLUMN`. Разрешает выполнять запросы `SHOW CREATE TABLE`, `DESCRIBE`. + - `SHOW DICTIONARIES`. Уровень: `DICTIONARY`. Разрешает выполнять запросы `SHOW DICTIONARIES`, `SHOW CREATE DICTIONARY`, `EXISTS `. -**Notes** +**Дополнительно** + +У пользователя есть привилегия `SHOW`, если ему присвоена любая другая привилегия по отношению к определенной таблице, словарю или базе данных. -A user has the `SHOW` privilege if it has any other privilege concerning the specified table, dictionary or database. ### KILL QUERY {#grant-kill-query} -Allows executing [KILL](../../sql-reference/statements/misc.md#kill-query-statement) queries according to the following hierarchy of privileges: +Разрешает выполнять запросы [KILL](misc.md#kill-query-statement) в соответствии со следующей иерархией привилегий: -Privilege level: `GLOBAL`. +Уровень: `GLOBAL`. -**Notes** +**Дополнительно** + +`KILL QUERY` позволяет пользователю останавливать запросы других пользователей. -`KILL QUERY` privilege allows one user to kill queries of other users. ### ACCESS MANAGEMENT {#grant-access-management} -Allows a user to execute queries that manage users, roles and row policies. +Разрешает пользователю выполнять запросы на управление пользователями, ролями и политиками доступа к строкам. -- `ACCESS MANAGEMENT`. Level: `GROUP` - - `CREATE USER`. Level: `GLOBAL` - - `ALTER USER`. Level: `GLOBAL` - - `DROP USER`. Level: `GLOBAL` - - `CREATE ROLE`. Level: `GLOBAL` - - `ALTER ROLE`. Level: `GLOBAL` - - `DROP ROLE`. Level: `GLOBAL` - - `ROLE ADMIN`. Level: `GLOBAL` - - `CREATE ROW POLICY`. Level: `GLOBAL`. Aliases: `CREATE POLICY` - - `ALTER ROW POLICY`. Level: `GLOBAL`. Aliases: `ALTER POLICY` - - `DROP ROW POLICY`. Level: `GLOBAL`. Aliases: `DROP POLICY` - - `CREATE QUOTA`. Level: `GLOBAL` - - `ALTER QUOTA`. Level: `GLOBAL` - - `DROP QUOTA`. Level: `GLOBAL` - - `CREATE SETTINGS PROFILE`. Level: `GLOBAL`. Aliases: `CREATE PROFILE` - - `ALTER SETTINGS PROFILE`. Level: `GLOBAL`. Aliases: `ALTER PROFILE` - - `DROP SETTINGS PROFILE`. Level: `GLOBAL`. Aliases: `DROP PROFILE` - - `SHOW ACCESS`. Level: `GROUP` - - `SHOW_USERS`. Level: `GLOBAL`. Aliases: `SHOW CREATE USER` - - `SHOW_ROLES`. Level: `GLOBAL`. Aliases: `SHOW CREATE ROLE` - - `SHOW_ROW_POLICIES`. Level: `GLOBAL`. Aliases: `SHOW POLICIES`, `SHOW CREATE ROW POLICY`, `SHOW CREATE POLICY` - - `SHOW_QUOTAS`. Level: `GLOBAL`. Aliases: `SHOW CREATE QUOTA` - - `SHOW_SETTINGS_PROFILES`. Level: `GLOBAL`. Aliases: `SHOW PROFILES`, `SHOW CREATE SETTINGS PROFILE`, `SHOW CREATE PROFILE` +- `ACCESS MANAGEMENT`. Уровень: `GROUP` + - `CREATE USER`. Уровень: `GLOBAL` + - `ALTER USER`. Уровень: `GLOBAL` + - `DROP USER`. Уровень: `GLOBAL` + - `CREATE ROLE`. Уровень: `GLOBAL` + - `ALTER ROLE`. Уровень: `GLOBAL` + - `DROP ROLE`. Уровень: `GLOBAL` + - `ROLE ADMIN`. Уровень: `GLOBAL` + - `CREATE ROW POLICY`. Уровень: `GLOBAL`. Алиасы: `CREATE POLICY` + - `ALTER ROW POLICY`. Уровень: `GLOBAL`. Алиасы: `ALTER POLICY` + - `DROP ROW POLICY`. Уровень: `GLOBAL`. Алиасы: `DROP POLICY` + - `CREATE QUOTA`. Уровень: `GLOBAL` + - `ALTER QUOTA`. Уровень: `GLOBAL` + - `DROP QUOTA`. Уровень: `GLOBAL` + - `CREATE SETTINGS PROFILE`. Уровень: `GLOBAL`. Алиасы: `CREATE PROFILE` + - `ALTER SETTINGS PROFILE`. Уровень: `GLOBAL`. Алиасы: `ALTER PROFILE` + - `DROP SETTINGS PROFILE`. Уровень: `GLOBAL`. Алиасы: `DROP PROFILE` + - `SHOW ACCESS`. Уровень: `GROUP` + - `SHOW_USERS`. Уровень: `GLOBAL`. Алиасы: `SHOW CREATE USER` + - `SHOW_ROLES`. Уровень: `GLOBAL`. Алиасы: `SHOW CREATE ROLE` + - `SHOW_ROW_POLICIES`. Уровень: `GLOBAL`. Алиасы: `SHOW POLICIES`, `SHOW CREATE ROW POLICY`, `SHOW CREATE POLICY` + - `SHOW_QUOTAS`. Уровень: `GLOBAL`. Алиасы: `SHOW CREATE QUOTA` + - `SHOW_SETTINGS_PROFILES`. Уровень: `GLOBAL`. Алиасы: `SHOW PROFILES`, `SHOW CREATE SETTINGS PROFILE`, `SHOW CREATE PROFILE` -The `ROLE ADMIN` privilege allows a user to assign and revoke any roles including those which are not assigned to the user with the admin option. +Привилегия `ROLE ADMIN` разрешает пользователю назначать и отзывать любые роли, включая те, которые не назначены пользователю с опцией администратора. ### SYSTEM {#grant-system} -Allows a user to execute [SYSTEM](../../sql-reference/statements/system.md) queries according to the following hierarchy of privileges. +Разрешает выполнять запросы [SYSTEM](system.md) в соответствии со следующей иерархией привилегий: -- `SYSTEM`. Level: `GROUP` - - `SYSTEM SHUTDOWN`. Level: `GLOBAL`. Aliases: `SYSTEM KILL`, `SHUTDOWN` - - `SYSTEM DROP CACHE`. Aliases: `DROP CACHE` - - `SYSTEM DROP DNS CACHE`. Level: `GLOBAL`. Aliases: `SYSTEM DROP DNS`, `DROP DNS CACHE`, `DROP DNS` - - `SYSTEM DROP MARK CACHE`. Level: `GLOBAL`. Aliases: `SYSTEM DROP MARK`, `DROP MARK CACHE`, `DROP MARKS` - - `SYSTEM DROP UNCOMPRESSED CACHE`. Level: `GLOBAL`. Aliases: `SYSTEM DROP UNCOMPRESSED`, `DROP UNCOMPRESSED CACHE`, `DROP UNCOMPRESSED` - - `SYSTEM RELOAD`. Level: `GROUP` - - `SYSTEM RELOAD CONFIG`. Level: `GLOBAL`. Aliases: `RELOAD CONFIG` - - `SYSTEM RELOAD DICTIONARY`. Level: `GLOBAL`. Aliases: `SYSTEM RELOAD DICTIONARIES`, `RELOAD DICTIONARY`, `RELOAD DICTIONARIES` - - `SYSTEM RELOAD EMBEDDED DICTIONARIES`. Level: `GLOBAL`. Aliases: R`ELOAD EMBEDDED DICTIONARIES` - - `SYSTEM MERGES`. Level: `TABLE`. Aliases: `SYSTEM STOP MERGES`, `SYSTEM START MERGES`, `STOP MERGES`, `START MERGES` - - `SYSTEM TTL MERGES`. Level: `TABLE`. Aliases: `SYSTEM STOP TTL MERGES`, `SYSTEM START TTL MERGES`, `STOP TTL MERGES`, `START TTL MERGES` - - `SYSTEM FETCHES`. Level: `TABLE`. Aliases: `SYSTEM STOP FETCHES`, `SYSTEM START FETCHES`, `STOP FETCHES`, `START FETCHES` - - `SYSTEM MOVES`. Level: `TABLE`. Aliases: `SYSTEM STOP MOVES`, `SYSTEM START MOVES`, `STOP MOVES`, `START MOVES` - - `SYSTEM SENDS`. Level: `GROUP`. Aliases: `SYSTEM STOP SENDS`, `SYSTEM START SENDS`, `STOP SENDS`, `START SENDS` - - `SYSTEM DISTRIBUTED SENDS`. Level: `TABLE`. Aliases: `SYSTEM STOP DISTRIBUTED SENDS`, `SYSTEM START DISTRIBUTED SENDS`, `STOP DISTRIBUTED SENDS`, `START DISTRIBUTED SENDS` - - `SYSTEM REPLICATED SENDS`. Level: `TABLE`. Aliases: `SYSTEM STOP REPLICATED SENDS`, `SYSTEM START REPLICATED SENDS`, `STOP REPLICATED SENDS`, `START REPLICATED SENDS` - - `SYSTEM REPLICATION QUEUES`. Level: `TABLE`. Aliases: `SYSTEM STOP REPLICATION QUEUES`, `SYSTEM START REPLICATION QUEUES`, `STOP REPLICATION QUEUES`, `START REPLICATION QUEUES` - - `SYSTEM SYNC REPLICA`. Level: `TABLE`. Aliases: `SYNC REPLICA` - - `SYSTEM RESTART REPLICA`. Level: `TABLE`. Aliases: `RESTART REPLICA` - - `SYSTEM FLUSH`. Level: `GROUP` - - `SYSTEM FLUSH DISTRIBUTED`. Level: `TABLE`. Aliases: `FLUSH DISTRIBUTED` - - `SYSTEM FLUSH LOGS`. Level: `GLOBAL`. Aliases: `FLUSH LOGS` +- `SYSTEM`. Уровень: `GROUP` + - `SYSTEM SHUTDOWN`. Уровень: `GLOBAL`. Алиасы: `SYSTEM KILL`, `SHUTDOWN` + - `SYSTEM DROP CACHE`. Алиасы: `DROP CACHE` + - `SYSTEM DROP DNS CACHE`. Уровень: `GLOBAL`. Алиасы: `SYSTEM DROP DNS`, `DROP DNS CACHE`, `DROP DNS` + - `SYSTEM DROP MARK CACHE`. Уровень: `GLOBAL`. Алиасы: `SYSTEM DROP MARK`, `DROP MARK CACHE`, `DROP MARKS` + - `SYSTEM DROP UNCOMPRESSED CACHE`. Уровень: `GLOBAL`. Алиасы: `SYSTEM DROP UNCOMPRESSED`, `DROP UNCOMPRESSED CACHE`, `DROP UNCOMPRESSED` + - `SYSTEM RELOAD`. Уровень: `GROUP` + - `SYSTEM RELOAD CONFIG`. Уровень: `GLOBAL`. Алиасы: `RELOAD CONFIG` + - `SYSTEM RELOAD DICTIONARY`. Уровень: `GLOBAL`. Алиасы: `SYSTEM RELOAD DICTIONARIES`, `RELOAD DICTIONARY`, `RELOAD DICTIONARIES` + - `SYSTEM RELOAD EMBEDDED DICTIONARIES`. Уровень: `GLOBAL`. Алиасы: `RELOAD EMBEDDED DICTIONARIES` + - `SYSTEM MERGES`. Уровень: `TABLE`. Алиасы: `SYSTEM STOP MERGES`, `SYSTEM START MERGES`, `STOP MERGES`, `START MERGES` + - `SYSTEM TTL MERGES`. Уровень: `TABLE`. Алиасы: `SYSTEM STOP TTL MERGES`, `SYSTEM START TTL MERGES`, `STOP TTL MERGES`, `START TTL MERGES` + - `SYSTEM FETCHES`. Уровень: `TABLE`. Алиасы: `SYSTEM STOP FETCHES`, `SYSTEM START FETCHES`, `STOP FETCHES`, `START FETCHES` + - `SYSTEM MOVES`. Уровень: `TABLE`. Алиасы: `SYSTEM STOP MOVES`, `SYSTEM START MOVES`, `STOP MOVES`, `START MOVES` + - `SYSTEM SENDS`. Уровень: `GROUP`. Алиасы: `SYSTEM STOP SENDS`, `SYSTEM START SENDS`, `STOP SENDS`, `START SENDS` + - `SYSTEM DISTRIBUTED SENDS`. Уровень: `TABLE`. Алиасы: `SYSTEM STOP DISTRIBUTED SENDS`, `SYSTEM START DISTRIBUTED SENDS`, `STOP DISTRIBUTED SENDS`, `START DISTRIBUTED SENDS` + - `SYSTEM REPLICATED SENDS`. Уровень: `TABLE`. Алиасы: `SYSTEM STOP REPLICATED SENDS`, `SYSTEM START REPLICATED SENDS`, `STOP REPLICATED SENDS`, `START REPLICATED SENDS` + - `SYSTEM REPLICATION QUEUES`. Уровень: `TABLE`. Алиасы: `SYSTEM STOP REPLICATION QUEUES`, `SYSTEM START REPLICATION QUEUES`, `STOP REPLICATION QUEUES`, `START REPLICATION QUEUES` + - `SYSTEM SYNC REPLICA`. Уровень: `TABLE`. Алиасы: `SYNC REPLICA` + - `SYSTEM RESTART REPLICA`. Уровень: `TABLE`. Алиасы: `RESTART REPLICA` + - `SYSTEM FLUSH`. Уровень: `GROUP` + - `SYSTEM FLUSH DISTRIBUTED`. Уровень: `TABLE`. Алиасы: `FLUSH DISTRIBUTED` + - `SYSTEM FLUSH LOGS`. Уровень: `GLOBAL`. Алиасы: `FLUSH LOGS` + +Привилегия `SYSTEM RELOAD EMBEDDED DICTIONARIES` имплицитно присваивается привилегией `SYSTEM RELOAD DICTIONARY ON *.*`. -The `SYSTEM RELOAD EMBEDDED DICTIONARIES` privilege implicitly granted by the `SYSTEM RELOAD DICTIONARY ON *.*` privilege. ### INTROSPECTION {#grant-introspection} -Allows using [introspection](../../operations/optimizing-performance/sampling-query-profiler.md) functions. +Разрешает использовать функции [интроспекции](../../operations/optimizing-performance/sampling-query-profiler.md). + +- `INTROSPECTION`. Уровень: `GROUP`. Алиасы: `INTROSPECTION FUNCTIONS` + - `addressToLine`. Уровень: `GLOBAL` + - `addressToSymbol`. Уровень: `GLOBAL` + - `demangle`. Уровень: `GLOBAL` -- `INTROSPECTION`. Level: `GROUP`. Aliases: `INTROSPECTION FUNCTIONS` - - `addressToLine`. Level: `GLOBAL` - - `addressToSymbol`. Level: `GLOBAL` - - `demangle`. Level: `GLOBAL` ### SOURCES {#grant-sources} -Allows using external data sources. Applies to [table engines](../../engines/table-engines/index.md) and [table functions](../../sql-reference/table-functions/index.md#table-functions). +Разрешает использовать внешние источники данных. Применяется к [движкам таблиц](../../engines/table-engines/index.md) и [табличным функциям](../table-functions/index.md#table-functions). -- `SOURCES`. Level: `GROUP` - - `FILE`. Level: `GLOBAL` - - `URL`. Level: `GLOBAL` - - `REMOTE`. Level: `GLOBAL` - - `MYSQL`. Level: `GLOBAL` - - `ODBC`. Level: `GLOBAL` - - `JDBC`. Level: `GLOBAL` - - `HDFS`. Level: `GLOBAL` - - `S3`. Level: `GLOBAL` +- `SOURCES`. Уровень: `GROUP` + - `FILE`. Уровень: `GLOBAL` + - `URL`. Уровень: `GLOBAL` + - `REMOTE`. Уровень: `GLOBAL` + - `YSQL`. Уровень: `GLOBAL` + - `ODBC`. Уровень: `GLOBAL` + - `JDBC`. Уровень: `GLOBAL` + - `HDFS`. Уровень: `GLOBAL` + - `S3`. Уровень: `GLOBAL` -The `SOURCES` privilege enables use of all the sources. Also you can grant a privilege for each source individually. To use sources, you need additional privileges. +Привилегия `SOURCES` разрешает использование всех источников. Также вы можете присвоить привилегию для каждого источника отдельно. Для использования источников необходимы дополнительные привилегии. -Examples: +Примеры: -- To create a table with the [MySQL table engine](../../engines/table-engines/integrations/mysql.md), you need `CREATE TABLE (ON db.table_name)` and `MYSQL` privileges. -- To use the [mysql table function](../../sql-reference/table-functions/mysql.md), you need `CREATE TEMPORARY TABLE` and `MYSQL` privileges. +- Чтобы создать таблицу с [движком MySQL](../../engines/table-engines/integrations/mysql.md), необходимы привилегии `CREATE TABLE (ON db.table_name)` и `MYSQL`. +- Чтобы использовать [табличную функцию mysql](../table-functions/mysql.md), необходимы привилегии `CREATE TEMPORARY TABLE` и `MYSQL`. ### dictGet {#grant-dictget} -- `dictGet`. Aliases: `dictHas`, `dictGetHierarchy`, `dictIsIn` +- `dictGet`. Алиасы: `dictHas`, `dictGetHierarchy`, `dictIsIn` -Allows a user to execute [dictGet](../../sql-reference/functions/ext-dict-functions.md#dictget), [dictHas](../../sql-reference/functions/ext-dict-functions.md#dicthas), [dictGetHierarchy](../../sql-reference/functions/ext-dict-functions.md#dictgethierarchy), [dictIsIn](../../sql-reference/functions/ext-dict-functions.md#dictisin) functions. +Разрешает вызывать функции [dictGet](../functions/ext-dict-functions.md#dictget), [dictHas](../functions/ext-dict-functions.md#dicthas), [dictGetHierarchy](../functions/ext-dict-functions.md#dictgethierarchy), [dictIsIn](../functions/ext-dict-functions.md#dictisin). -Privilege level: `DICTIONARY`. +Уровень: `DICTIONARY`. -**Examples** +**Примеры** -- `GRANT dictGet ON mydb.mydictionary TO john` -- `GRANT dictGet ON mydictionary TO john` +- `GRANT dictGet ON mydb.mydictionary TO john` +- `GRANT dictGet ON mydictionary TO john` ### ALL {#grant-all} -Grants all the privileges on regulated entity to a user account or a role. +Присваивает пользователю или роли все привилегии на объект с регулируемым доступом. + ### NONE {#grant-none} -Doesn’t grant any privileges. +Не присваивает никаких привилегий. + ### ADMIN OPTION {#admin-option-privilege} -The `ADMIN OPTION` privilege allows a user to grant their role to another user. +Привилегия `ADMIN OPTION` разрешает пользователю назначать свои роли другому пользователю. -[Original article](https://clickhouse.tech/docs/en/query_language/grant/) +[Оригинальная статья](https://clickhouse.tech/docs/ru/sql-reference/statements/grant/) diff --git a/docs/tools/purge_cache_for_changed_files.py b/docs/tools/purge_cache_for_changed_files.py new file mode 100644 index 00000000000..761697770b7 --- /dev/null +++ b/docs/tools/purge_cache_for_changed_files.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +import subprocess +import requests +import os +import time + +FNAME_START = "+++" + +CLOUDFLARE_URL = "https://api.cloudflare.com/client/v4/zones/4fc6fb1d46e87851605aa7fa69ca6fe0/purge_cache" + +# we have changes in revision and commit sha on all pages +# so such changes have to be ignored +MIN_CHANGED_WORDS = 4 + + +def collect_changed_files(): + proc = subprocess.Popen("git diff HEAD~1 --word-diff=porcelain | grep -e '^+[^+]\|^\-[^\-]\|^\+\+\+'", stdout=subprocess.PIPE, shell=True) + changed_files = [] + current_file_name = "" + changed_words = [] + while True: + line = proc.stdout.readline().decode("utf-8").strip() + if not line: + break + if FNAME_START in line: + if changed_words: + if len(changed_words) > MIN_CHANGED_WORDS: + changed_files.append(current_file_name) + changed_words = [] + current_file_name = line[6:] + else: + changed_words.append(line) + return changed_files + + +def filter_and_transform_changed_files(changed_files, base_domain): + result = [] + for f in changed_files: + if f.endswith(".html"): + result.append(base_domain + f.replace("index.html", "")) + return result + + +def convert_to_dicts(changed_files, batch_size): + result = [] + current_batch = {"files": []} + for f in changed_files: + if len(current_batch["files"]) >= batch_size: + result.append(current_batch) + current_batch = {"files": []} + current_batch["files"].append(f) + + if current_batch["files"]: + result.append(current_batch) + return result + + +def post_data(prepared_batches, token): + headers = {"Authorization": "Bearer {}".format(token)} + for batch in prepared_batches: + print("Pugring cache for", ", ".join(batch["files"])) + response = requests.post(CLOUDFLARE_URL, json=batch, headers=headers) + response.raise_for_status() + time.sleep(3) + + +if __name__ == "__main__": + token = os.getenv("CLOUDFLARE_TOKEN") + if not token: + raise Exception("Env variable CLOUDFLARE_TOKEN is empty") + base_domain = os.getenv("BASE_DOMAIN", "https://content.clickhouse.tech/") + changed_files = collect_changed_files() + print("Found", len(changed_files), "changed files") + filtered_files = filter_and_transform_changed_files(changed_files, base_domain) + print("Files rest after filtering", len(filtered_files)) + prepared_batches = convert_to_dicts(filtered_files, 25) + post_data(prepared_batches, token) diff --git a/docs/tools/release.sh b/docs/tools/release.sh index c3fb0615677..e539e01e808 100755 --- a/docs/tools/release.sh +++ b/docs/tools/release.sh @@ -10,13 +10,6 @@ GIT_PROD_URI="git@github.com:ClickHouse/clickhouse-website-content.git" EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS:---enable-stable-releases --minify --verbose}" HISTORY_SIZE="${HISTORY_SIZE:-5}" -if [[ -z "$1" ]] -then - TAG=$(head -c 8 /dev/urandom | xxd -p) -else - TAG="$1" -fi -DOCKER_HASH="$2" if [[ -z "$1" ]] then source "${BASE_DIR}/venv/bin/activate" @@ -44,27 +37,6 @@ then if [[ ! -z "${CLOUDFLARE_TOKEN}" ]] then sleep 1m - git diff --stat="9999,9999" --diff-filter=M HEAD~1 | grep '|' | awk '$1 ~ /\.html$/ { if ($3>6) { url="https://content.clickhouse.tech/"$1; sub(/index.html/, "", url); print "\""url"\""; }}' | split -l 25 /dev/stdin PURGE - for FILENAME in $(ls PURGE*) - do - POST_DATA=$(cat "${FILENAME}" | sed -n -e 'H;${x;s/\n/,/g;s/^,//;p;}' | awk '{print "{\"files\":["$0"]}";}') - sleep 3s - set +x - curl -X POST "https://api.cloudflare.com/client/v4/zones/4fc6fb1d46e87851605aa7fa69ca6fe0/purge_cache" -H "Authorization: Bearer ${CLOUDFLARE_TOKEN}" -H "Content-Type:application/json" --data "${POST_DATA}" - set -x - rm "${FILENAME}" - done + python3 "${BASE_DIR}/purge_cache_for_changed_files.py" fi - cd "${BUILD_DIR}" - DOCKER_HASH=$(head -c 16 < /dev/urandom | xxd -p) fi - -QLOUD_ENDPOINT="https://platform.yandex-team.ru/api/v1" -QLOUD_PROJECT="clickhouse.clickhouse-website" -if [[ -z "$1" ]] -then - QLOUD_ENV="${QLOUD_PROJECT}.test" -else - QLOUD_ENV="${QLOUD_PROJECT}.prod" -fi -echo ">>> Successfully deployed ${TAG} ${DOCKER_HASH} to ${QLOUD_ENV} <<<" diff --git a/programs/copier/ClusterCopierApp.cpp b/programs/copier/ClusterCopierApp.cpp index e702d2f6353..d6ec5a7e8ad 100644 --- a/programs/copier/ClusterCopierApp.cpp +++ b/programs/copier/ClusterCopierApp.cpp @@ -106,7 +106,7 @@ void ClusterCopierApp::mainImpl() context->setConfig(loaded_config.configuration); context->setApplicationType(Context::ApplicationType::LOCAL); - context->setPath(process_path); + context->setPath(process_path + "/"); registerFunctions(); registerAggregateFunctions(); diff --git a/src/Client/Connection.cpp b/src/Client/Connection.cpp index 367d4bab1dc..3bb8af72516 100644 --- a/src/Client/Connection.cpp +++ b/src/Client/Connection.cpp @@ -1,5 +1,3 @@ -#include - #include #include #include diff --git a/src/Columns/Collator.cpp b/src/Columns/Collator.cpp index 77735564077..d33f65e3836 100644 --- a/src/Columns/Collator.cpp +++ b/src/Columns/Collator.cpp @@ -17,7 +17,6 @@ #endif #include -#include #include #include diff --git a/src/Columns/ColumnAggregateFunction.cpp b/src/Columns/ColumnAggregateFunction.cpp index 4b9dcc8d04e..b9200ffe910 100644 --- a/src/Columns/ColumnAggregateFunction.cpp +++ b/src/Columns/ColumnAggregateFunction.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include diff --git a/src/Columns/ColumnConst.cpp b/src/Columns/ColumnConst.cpp index 2fa1fbce32d..b7fb22aeb0e 100644 --- a/src/Columns/ColumnConst.cpp +++ b/src/Columns/ColumnConst.cpp @@ -2,11 +2,9 @@ #include #include -#include #include #include #include -#include #if defined(MEMORY_SANITIZER) #include diff --git a/src/Columns/ColumnString.cpp b/src/Columns/ColumnString.cpp index 99c99e2ea90..467a8681868 100644 --- a/src/Columns/ColumnString.cpp +++ b/src/Columns/ColumnString.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Columns/ColumnVector.cpp b/src/Columns/ColumnVector.cpp index 8c6768b92e8..0fea73d2bce 100644 --- a/src/Columns/ColumnVector.cpp +++ b/src/Columns/ColumnVector.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/src/Common/Config/ConfigProcessor.cpp b/src/Common/Config/ConfigProcessor.cpp index bf65b7028cc..0e36c6ee660 100644 --- a/src/Common/Config/ConfigProcessor.cpp +++ b/src/Common/Config/ConfigProcessor.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/src/Common/Config/configReadClient.cpp b/src/Common/Config/configReadClient.cpp index 01ad421cc2b..61d8e507c05 100644 --- a/src/Common/Config/configReadClient.cpp +++ b/src/Common/Config/configReadClient.cpp @@ -1,6 +1,5 @@ #include "configReadClient.h" -#include #include #include #include "ConfigProcessor.h" diff --git a/src/Common/ErrorCodes.cpp b/src/Common/ErrorCodes.cpp index 59c99a61371..a4abaf91231 100644 --- a/src/Common/ErrorCodes.cpp +++ b/src/Common/ErrorCodes.cpp @@ -497,6 +497,9 @@ namespace ErrorCodes extern const int CANNOT_CONNECT_RABBITMQ = 530; extern const int CANNOT_FSTAT = 531; extern const int LDAP_ERROR = 532; + extern const int INCONSISTENT_RESERVATIONS = 533; + extern const int NO_RESERVATIONS_PROVIDED = 534; + extern const int UNKNOWN_RAID_TYPE = 535; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/src/Common/FieldVisitors.cpp b/src/Common/FieldVisitors.cpp index 8b0bfacbd48..4ac87dfdd24 100644 --- a/src/Common/FieldVisitors.cpp +++ b/src/Common/FieldVisitors.cpp @@ -1,9 +1,7 @@ #include #include #include -#include #include -#include #include #include #include diff --git a/src/Common/ProfileEvents.cpp b/src/Common/ProfileEvents.cpp index eceb082f524..908adbe1d12 100644 --- a/src/Common/ProfileEvents.cpp +++ b/src/Common/ProfileEvents.cpp @@ -117,6 +117,8 @@ M(SelectedParts, "Number of data parts selected to read from a MergeTree table.") \ M(SelectedRanges, "Number of (non-adjacent) ranges in all data parts selected to read from a MergeTree table.") \ M(SelectedMarks, "Number of marks (index granules) selected to read from a MergeTree table.") \ + M(SelectedRows, "Number of rows SELECTed from all tables.") \ + M(SelectedBytes, "Number of bytes (uncompressed; for columns as they stored in memory) SELECTed from all tables.") \ \ M(Merge, "Number of launched background merges.") \ M(MergedRows, "Rows read for background merges. This is the number of rows before merge.") \ diff --git a/src/Common/QueryProfiler.cpp b/src/Common/QueryProfiler.cpp index c4c7d21314d..07e145359d8 100644 --- a/src/Common/QueryProfiler.cpp +++ b/src/Common/QueryProfiler.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/src/Common/StatusFile.cpp b/src/Common/StatusFile.cpp index 3766908f9cd..7c6bbf814a0 100644 --- a/src/Common/StatusFile.cpp +++ b/src/Common/StatusFile.cpp @@ -1,7 +1,5 @@ #include "StatusFile.h" -#include -#include #include #include #include diff --git a/src/Common/ThreadFuzzer.cpp b/src/Common/ThreadFuzzer.cpp index 0e7c5429ade..a32e50c44b2 100644 --- a/src/Common/ThreadFuzzer.cpp +++ b/src/Common/ThreadFuzzer.cpp @@ -1,5 +1,4 @@ #include -#include #include #if defined(OS_LINUX) # include @@ -8,9 +7,7 @@ #include -#include #include -#include #include diff --git a/src/Common/TraceCollector.cpp b/src/Common/TraceCollector.cpp index f5bdfd2b826..eb87f95bd7b 100644 --- a/src/Common/TraceCollector.cpp +++ b/src/Common/TraceCollector.cpp @@ -13,9 +13,6 @@ #include #include -#include -#include - namespace DB { diff --git a/src/Common/ZooKeeper/IKeeper.cpp b/src/Common/ZooKeeper/IKeeper.cpp index cb378ba1e13..ad18fdd992a 100644 --- a/src/Common/ZooKeeper/IKeeper.cpp +++ b/src/Common/ZooKeeper/IKeeper.cpp @@ -1,5 +1,3 @@ -#include - #include #include diff --git a/src/Common/ZooKeeper/ZooKeeper.cpp b/src/Common/ZooKeeper/ZooKeeper.cpp index 476e88d7e72..e50aa8f1700 100644 --- a/src/Common/ZooKeeper/ZooKeeper.cpp +++ b/src/Common/ZooKeeper/ZooKeeper.cpp @@ -3,7 +3,6 @@ #include "KeeperException.h" #include "TestKeeper.h" -#include #include #include @@ -11,8 +10,6 @@ #include #include #include -#include -#include #include #include diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.cpp b/src/Common/ZooKeeper/ZooKeeperImpl.cpp index 61a64f2c51f..85fc1cd9f79 100644 --- a/src/Common/ZooKeeper/ZooKeeperImpl.cpp +++ b/src/Common/ZooKeeper/ZooKeeperImpl.cpp @@ -8,9 +8,6 @@ #include #include -#include -#include - #if !defined(ARCADIA_BUILD) # include #endif diff --git a/src/Common/ZooKeeper/tests/gtest_zkutil_test_multi_exception.cpp b/src/Common/ZooKeeper/tests/gtest_zkutil_test_multi_exception.cpp index 19104e02e24..de60d382301 100644 --- a/src/Common/ZooKeeper/tests/gtest_zkutil_test_multi_exception.cpp +++ b/src/Common/ZooKeeper/tests/gtest_zkutil_test_multi_exception.cpp @@ -12,7 +12,9 @@ using namespace DB; -TEST(zkutil, ZookeeperConnected) + +template +auto getZooKeeper(Args &&... args) { /// In our CI infrastructure it is typical that ZooKeeper is unavailable for some amount of time. size_t i; @@ -20,9 +22,10 @@ TEST(zkutil, ZookeeperConnected) { try { - auto zookeeper = std::make_unique("localhost:2181"); + auto zookeeper = std::make_unique("localhost:2181", std::forward(args)...); zookeeper->exists("/"); zookeeper->createIfNotExists("/clickhouse_test", "Unit tests of ClickHouse"); + return zookeeper; } catch (...) { @@ -30,18 +33,16 @@ TEST(zkutil, ZookeeperConnected) sleep(1); continue; } - break; - } - if (i == 100) - { - std::cerr << "No zookeeper after " << i << " tries. skip tests." << std::endl; - exit(0); } + + std::cerr << "No zookeeper after " << i << " tries. skip tests." << std::endl; + exit(0); } + TEST(zkutil, MultiNiceExceptionMsg) { - auto zookeeper = std::make_unique("localhost:2181"); + auto zookeeper = getZooKeeper(); Coordination::Requests ops; @@ -79,13 +80,13 @@ TEST(zkutil, MultiNiceExceptionMsg) TEST(zkutil, MultiAsync) { - auto zookeeper = std::make_unique("localhost:2181"); Coordination::Requests ops; - zookeeper->tryRemoveRecursive("/clickhouse_test/zkutil_multi"); + getZooKeeper()->tryRemoveRecursive("/clickhouse_test/zkutil_multi"); { ops.clear(); + auto zookeeper = getZooKeeper(); auto fut = zookeeper->asyncMulti(ops); } @@ -94,6 +95,7 @@ TEST(zkutil, MultiAsync) ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi", "", zkutil::CreateMode::Persistent)); ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/a", "", zkutil::CreateMode::Persistent)); + auto zookeeper = getZooKeeper(); auto fut = zookeeper->tryAsyncMulti(ops); ops.clear(); @@ -104,6 +106,7 @@ TEST(zkutil, MultiAsync) EXPECT_ANY_THROW ( + auto zookeeper = getZooKeeper(); std::vector> futures; for (size_t i = 0; i < 10000; ++i) @@ -131,6 +134,7 @@ TEST(zkutil, MultiAsync) ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi", "_", zkutil::CreateMode::Persistent)); ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/a", "_", zkutil::CreateMode::Persistent)); + auto zookeeper = getZooKeeper(); auto fut = zookeeper->tryAsyncMulti(ops); ops.clear(); @@ -155,16 +159,15 @@ TEST(zkutil, WatchGetChildrenWithChroot) { try { - const String zk_server = "localhost:2181"; const String prefix = "/clickhouse_test/zkutil/watch_get_children_with_chroot"; /// Create chroot node firstly - auto zookeeper = std::make_unique(zk_server); + auto zookeeper = getZooKeeper(); zookeeper->createAncestors(prefix + "/"); - zookeeper = std::make_unique(zk_server, "", - zkutil::DEFAULT_SESSION_TIMEOUT, - zkutil::DEFAULT_OPERATION_TIMEOUT, - prefix); + zookeeper = getZooKeeper("", + zkutil::DEFAULT_SESSION_TIMEOUT, + zkutil::DEFAULT_OPERATION_TIMEOUT, + prefix); String queue_path = "/queue"; zookeeper->tryRemoveRecursive(queue_path); @@ -173,10 +176,10 @@ TEST(zkutil, WatchGetChildrenWithChroot) zkutil::EventPtr event = std::make_shared(); zookeeper->getChildren(queue_path, nullptr, event); { - auto zookeeper2 = std::make_unique(zk_server, "", - zkutil::DEFAULT_SESSION_TIMEOUT, - zkutil::DEFAULT_OPERATION_TIMEOUT, - prefix); + auto zookeeper2 = getZooKeeper("", + zkutil::DEFAULT_SESSION_TIMEOUT, + zkutil::DEFAULT_OPERATION_TIMEOUT, + prefix); zookeeper2->create(queue_path + "/children-", "", zkutil::CreateMode::PersistentSequential); } event->wait(); @@ -192,16 +195,15 @@ TEST(zkutil, MultiCreateSequential) { try { - const String zk_server = "localhost:2181"; const String prefix = "/clickhouse_test/zkutil"; /// Create chroot node firstly - auto zookeeper = std::make_unique(zk_server); + auto zookeeper = getZooKeeper(); zookeeper->createAncestors(prefix + "/"); - zookeeper = std::make_unique(zk_server, "", - zkutil::DEFAULT_SESSION_TIMEOUT, - zkutil::DEFAULT_OPERATION_TIMEOUT, - "/clickhouse_test"); + zookeeper = getZooKeeper("", + zkutil::DEFAULT_SESSION_TIMEOUT, + zkutil::DEFAULT_OPERATION_TIMEOUT, + "/clickhouse_test"); String base_path = "/multi_create_sequential"; zookeeper->tryRemoveRecursive(base_path); diff --git a/src/Common/hasLinuxCapability.cpp b/src/Common/hasLinuxCapability.cpp index 94793050dbe..c71a5f6c9d6 100644 --- a/src/Common/hasLinuxCapability.cpp +++ b/src/Common/hasLinuxCapability.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include diff --git a/src/Compression/CompressedReadBuffer.cpp b/src/Compression/CompressedReadBuffer.cpp index a5eb59e1f59..043fbdcdc1b 100644 --- a/src/Compression/CompressedReadBuffer.cpp +++ b/src/Compression/CompressedReadBuffer.cpp @@ -1,5 +1,4 @@ #include "CompressedReadBuffer.h" -#include #include diff --git a/src/Compression/CompressedReadBufferBase.cpp b/src/Compression/CompressedReadBufferBase.cpp index 60689b81dac..faee8f67a2c 100644 --- a/src/Compression/CompressedReadBufferBase.cpp +++ b/src/Compression/CompressedReadBufferBase.cpp @@ -1,14 +1,11 @@ #include "CompressedReadBufferBase.h" -#include #include #include #include -#include #include #include #include -#include #include #include #include diff --git a/src/Compression/CompressedReadBufferFromFile.cpp b/src/Compression/CompressedReadBufferFromFile.cpp index ddd8bba686f..8d6a42eacd3 100644 --- a/src/Compression/CompressedReadBufferFromFile.cpp +++ b/src/Compression/CompressedReadBufferFromFile.cpp @@ -2,7 +2,6 @@ #include "CompressedReadBufferFromFile.h" -#include #include #include #include diff --git a/src/Compression/CompressedWriteBuffer.cpp b/src/Compression/CompressedWriteBuffer.cpp index 993b2d179db..092da9e4364 100644 --- a/src/Compression/CompressedWriteBuffer.cpp +++ b/src/Compression/CompressedWriteBuffer.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/src/Compression/CompressionCodecDelta.cpp b/src/Compression/CompressionCodecDelta.cpp index 50f449bef51..c12d7753ddf 100644 --- a/src/Compression/CompressionCodecDelta.cpp +++ b/src/Compression/CompressionCodecDelta.cpp @@ -5,7 +5,6 @@ #include #include #include -#include namespace DB diff --git a/src/Compression/CompressionCodecGorilla.cpp b/src/Compression/CompressionCodecGorilla.cpp index 9038482c950..4a09d16963f 100644 --- a/src/Compression/CompressionCodecGorilla.cpp +++ b/src/Compression/CompressionCodecGorilla.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include diff --git a/src/Compression/CompressionCodecMultiple.cpp b/src/Compression/CompressionCodecMultiple.cpp index e5adacb6173..6f4ebca90b8 100644 --- a/src/Compression/CompressionCodecMultiple.cpp +++ b/src/Compression/CompressionCodecMultiple.cpp @@ -3,12 +3,10 @@ #include #include #include -#include #include #include #include #include -#include namespace DB diff --git a/src/Compression/CompressionCodecZSTD.cpp b/src/Compression/CompressionCodecZSTD.cpp index f1030d87ddd..7abf0303095 100644 --- a/src/Compression/CompressionCodecZSTD.cpp +++ b/src/Compression/CompressionCodecZSTD.cpp @@ -1,9 +1,7 @@ #include #include -#include #include #include -#include #include #include #include diff --git a/src/Compression/CompressionFactory.cpp b/src/Compression/CompressionFactory.cpp index e9dee053c2c..1df4c443699 100644 --- a/src/Compression/CompressionFactory.cpp +++ b/src/Compression/CompressionFactory.cpp @@ -1,10 +1,7 @@ #include -#include -#include #include #include #include -#include #include #include #include diff --git a/src/Compression/LZ4_decompress_faster.cpp b/src/Compression/LZ4_decompress_faster.cpp index 801b4925013..dc293941310 100644 --- a/src/Compression/LZ4_decompress_faster.cpp +++ b/src/Compression/LZ4_decompress_faster.cpp @@ -2,8 +2,6 @@ #include #include -#include -#include #include #include #include diff --git a/src/Compression/tests/compressed_buffer.cpp b/src/Compression/tests/compressed_buffer.cpp index 346a4068a6c..89bfe0d0cce 100644 --- a/src/Compression/tests/compressed_buffer.cpp +++ b/src/Compression/tests/compressed_buffer.cpp @@ -1,11 +1,9 @@ #include #include -#include #include #include -#include #include #include #include diff --git a/src/Compression/tests/gtest_compressionCodec.cpp b/src/Compression/tests/gtest_compressionCodec.cpp index edcb6050abb..b9c7a769345 100644 --- a/src/Compression/tests/gtest_compressionCodec.cpp +++ b/src/Compression/tests/gtest_compressionCodec.cpp @@ -11,8 +11,6 @@ #include #include -#include - #include #include #include diff --git a/src/Core/Block.cpp b/src/Core/Block.cpp index 453d4b7e4ce..07ec0810f96 100644 --- a/src/Core/Block.cpp +++ b/src/Core/Block.cpp @@ -6,13 +6,11 @@ #include #include -#include #include #include #include -#include namespace DB diff --git a/src/Core/ColumnWithTypeAndName.cpp b/src/Core/ColumnWithTypeAndName.cpp index 9acc2d56408..29da8e86439 100644 --- a/src/Core/ColumnWithTypeAndName.cpp +++ b/src/Core/ColumnWithTypeAndName.cpp @@ -1,6 +1,5 @@ #include #include -#include #include diff --git a/src/Core/ExternalResultDescription.cpp b/src/Core/ExternalResultDescription.cpp index 456cce74ef1..5ed34764909 100644 --- a/src/Core/ExternalResultDescription.cpp +++ b/src/Core/ExternalResultDescription.cpp @@ -7,7 +7,6 @@ #include #include #include -#include namespace DB diff --git a/src/Core/tests/field.cpp b/src/Core/tests/field.cpp index 6198288b507..b0a1c1151a6 100644 --- a/src/Core/tests/field.cpp +++ b/src/Core/tests/field.cpp @@ -1,12 +1,10 @@ #include #include -#include #include #include #include -#include #include #include diff --git a/src/DataStreams/IBlockInputStream.cpp b/src/DataStreams/IBlockInputStream.cpp index 66c747207e8..94f7544480a 100644 --- a/src/DataStreams/IBlockInputStream.cpp +++ b/src/DataStreams/IBlockInputStream.cpp @@ -9,6 +9,8 @@ namespace ProfileEvents { extern const Event ThrottlerSleepMicroseconds; + extern const Event SelectedRows; + extern const Event SelectedBytes; } @@ -263,6 +265,9 @@ void IBlockInputStream::progressImpl(const Progress & value) if (quota && limits.mode == LIMITS_TOTAL) quota->used({Quota::READ_ROWS, value.read_rows}, {Quota::READ_BYTES, value.read_bytes}); } + + ProfileEvents::increment(ProfileEvents::SelectedRows, value.read_rows); + ProfileEvents::increment(ProfileEvents::SelectedBytes, value.read_bytes); } diff --git a/src/DataTypes/DataTypeCustomGeo.cpp b/src/DataTypes/DataTypeCustomGeo.cpp index baffde700c8..73d76e7e1e8 100644 --- a/src/DataTypes/DataTypeCustomGeo.cpp +++ b/src/DataTypes/DataTypeCustomGeo.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/DataTypes/DataTypeCustomIPv4AndIPv6.cpp b/src/DataTypes/DataTypeCustomIPv4AndIPv6.cpp index 08f08b7cab9..78a1e18679d 100644 --- a/src/DataTypes/DataTypeCustomIPv4AndIPv6.cpp +++ b/src/DataTypes/DataTypeCustomIPv4AndIPv6.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include namespace DB diff --git a/src/DataTypes/DataTypeCustomSimpleAggregateFunction.cpp b/src/DataTypes/DataTypeCustomSimpleAggregateFunction.cpp index 2c0bb03991b..2583f4f2753 100644 --- a/src/DataTypes/DataTypeCustomSimpleAggregateFunction.cpp +++ b/src/DataTypes/DataTypeCustomSimpleAggregateFunction.cpp @@ -1,14 +1,9 @@ #include #include -#include - -#include - #include #include #include -#include #include #include diff --git a/src/DataTypes/DataTypeDateTime.cpp b/src/DataTypes/DataTypeDateTime.cpp index 773a237cdc2..c860766406e 100644 --- a/src/DataTypes/DataTypeDateTime.cpp +++ b/src/DataTypes/DataTypeDateTime.cpp @@ -1,10 +1,7 @@ #include -#include #include -#include #include -#include #include #include #include diff --git a/src/DataTypes/DataTypeDateTime64.cpp b/src/DataTypes/DataTypeDateTime64.cpp index 87da173766d..97dd28439d7 100644 --- a/src/DataTypes/DataTypeDateTime64.cpp +++ b/src/DataTypes/DataTypeDateTime64.cpp @@ -1,8 +1,6 @@ #include -#include #include -#include #include #include #include diff --git a/src/DataTypes/DataTypeFixedString.cpp b/src/DataTypes/DataTypeFixedString.cpp index e2a3a1244fa..e5c192085a4 100644 --- a/src/DataTypes/DataTypeFixedString.cpp +++ b/src/DataTypes/DataTypeFixedString.cpp @@ -1,5 +1,4 @@ #include -#include #include #include diff --git a/src/DataTypes/DataTypeString.cpp b/src/DataTypes/DataTypeString.cpp index 1d3253feece..9d563ee836c 100644 --- a/src/DataTypes/DataTypeString.cpp +++ b/src/DataTypes/DataTypeString.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include diff --git a/src/DataTypes/DataTypesNumber.cpp b/src/DataTypes/DataTypesNumber.cpp index 9504b923809..06b747e1d08 100644 --- a/src/DataTypes/DataTypesNumber.cpp +++ b/src/DataTypes/DataTypesNumber.cpp @@ -3,7 +3,6 @@ #include -#include namespace DB diff --git a/src/DataTypes/IDataType.cpp b/src/DataTypes/IDataType.cpp index c31b80b7973..561166cbc78 100644 --- a/src/DataTypes/IDataType.cpp +++ b/src/DataTypes/IDataType.cpp @@ -4,8 +4,6 @@ #include #include -#include - #include #include diff --git a/src/Dictionaries/CacheDictionary.cpp b/src/Dictionaries/CacheDictionary.cpp index 63d64492447..2f2be695a8f 100644 --- a/src/Dictionaries/CacheDictionary.cpp +++ b/src/Dictionaries/CacheDictionary.cpp @@ -1,6 +1,5 @@ #include "CacheDictionary.h" -#include #include #include #include diff --git a/src/Dictionaries/tests/gtest_dictionary_configuration.cpp b/src/Dictionaries/tests/gtest_dictionary_configuration.cpp index ae9c5385b8d..fc99a34cd42 100644 --- a/src/Dictionaries/tests/gtest_dictionary_configuration.cpp +++ b/src/Dictionaries/tests/gtest_dictionary_configuration.cpp @@ -1,16 +1,8 @@ -#include - -#include #include #include #include -#include #include #include -#include -#include -#include -#include #include #include #include diff --git a/src/Disks/IDisk.h b/src/Disks/IDisk.h index 0a977feb9a1..ea331c5f64b 100644 --- a/src/Disks/IDisk.h +++ b/src/Disks/IDisk.h @@ -25,6 +25,7 @@ using DiskDirectoryIteratorPtr = std::unique_ptr; class IReservation; using ReservationPtr = std::unique_ptr; +using Reservations = std::vector; class ReadBufferFromFileBase; class WriteBufferFromFileBase; diff --git a/src/Disks/IVolume.cpp b/src/Disks/IVolume.cpp index 6a122a3e3b2..95f03826591 100644 --- a/src/Disks/IVolume.cpp +++ b/src/Disks/IVolume.cpp @@ -10,10 +10,32 @@ namespace DB namespace ErrorCodes { extern const int EXCESSIVE_ELEMENT_IN_CONFIG; + extern const int INCONSISTENT_RESERVATIONS; + extern const int NO_RESERVATIONS_PROVIDED; + extern const int UNKNOWN_VOLUME_TYPE; +} + +String volumeTypeToString(VolumeType type) +{ + switch (type) + { + case VolumeType::JBOD: + return "JBOD"; + case VolumeType::RAID1: + return "RAID1"; + case VolumeType::SINGLE_DISK: + return "SINGLE_DISK"; + case VolumeType::UNKNOWN: + return "UNKNOWN"; + } + throw Exception("Unknown volume type, please add it to DB::volumeTypeToString", ErrorCodes::UNKNOWN_VOLUME_TYPE); } IVolume::IVolume( - String name_, const Poco::Util::AbstractConfiguration & config, const String & config_prefix, DiskSelectorPtr disk_selector) + String name_, + const Poco::Util::AbstractConfiguration & config, + const String & config_prefix, + DiskSelectorPtr disk_selector) : name(std::move(name_)) { Poco::Util::AbstractConfiguration::Keys keys; @@ -40,4 +62,43 @@ UInt64 IVolume::getMaxUnreservedFreeSpace() const return res; } +MultiDiskReservation::MultiDiskReservation(Reservations & reservations_, UInt64 size_) + : reservations(std::move(reservations_)) + , size(size_) +{ + if (reservations.empty()) + { + throw Exception("At least one reservation must be provided to MultiDiskReservation", ErrorCodes::NO_RESERVATIONS_PROVIDED); + } + + for (auto & reservation : reservations) + { + if (reservation->getSize() != size_) + { + throw Exception("Reservations must have same size", ErrorCodes::INCONSISTENT_RESERVATIONS); + } + } +} + +Disks MultiDiskReservation::getDisks() const +{ + Disks res; + res.reserve(reservations.size()); + for (const auto & reservation : reservations) + { + res.push_back(reservation->getDisk()); + } + return res; +} + +void MultiDiskReservation::update(UInt64 new_size) +{ + for (auto & reservation : reservations) + { + reservation->update(new_size); + } + size = new_size; +} + + } diff --git a/src/Disks/IVolume.h b/src/Disks/IVolume.h index a762958a33f..5e7f09e1d04 100644 --- a/src/Disks/IVolume.h +++ b/src/Disks/IVolume.h @@ -11,10 +11,13 @@ namespace DB enum class VolumeType { JBOD, + RAID1, SINGLE_DISK, UNKNOWN }; +String volumeTypeToString(VolumeType t); + class IVolume; using VolumePtr = std::shared_ptr; using Volumes = std::vector; @@ -33,7 +36,10 @@ using Volumes = std::vector; class IVolume : public Space { public: - IVolume(String name_, Disks disks_): disks(std::move(disks_)), name(name_) + IVolume(String name_, Disks disks_, size_t max_data_part_size_ = 0) + : disks(std::move(disks_)) + , name(name_) + , max_data_part_size(max_data_part_size_) { } @@ -53,12 +59,35 @@ public: /// Return biggest unreserved space across all disks UInt64 getMaxUnreservedFreeSpace() const; - DiskPtr getDisk(size_t i = 0) const { return disks[i]; } + DiskPtr getDisk() const { return getDisk(0); } + virtual DiskPtr getDisk(size_t i) const { return disks[i]; } const Disks & getDisks() const { return disks; } protected: Disks disks; const String name; + +public: + /// Max size of reservation, zero means unlimited size + UInt64 max_data_part_size = 0; +}; + +/// Reservation for multiple disks at once. Can be used in RAID1 implementation. +class MultiDiskReservation : public IReservation +{ +public: + MultiDiskReservation(Reservations & reservations, UInt64 size); + + UInt64 getSize() const override { return size; } + + DiskPtr getDisk(size_t i) const override { return reservations[i]->getDisk(); } + + Disks getDisks() const override; + + void update(UInt64 new_size) override; +private: + Reservations reservations; + UInt64 size; }; } diff --git a/src/Disks/SingleDiskVolume.h b/src/Disks/SingleDiskVolume.h index c7a6776a7d2..c441d4c2dd2 100644 --- a/src/Disks/SingleDiskVolume.h +++ b/src/Disks/SingleDiskVolume.h @@ -22,5 +22,6 @@ public: }; using VolumeSingleDiskPtr = std::shared_ptr; +using VolumesSingleDiskPtr = std::vector; } diff --git a/src/Disks/StoragePolicy.cpp b/src/Disks/StoragePolicy.cpp index f684dce0496..1aa20301bc0 100644 --- a/src/Disks/StoragePolicy.cpp +++ b/src/Disks/StoragePolicy.cpp @@ -71,7 +71,7 @@ StoragePolicy::StoragePolicy( } -StoragePolicy::StoragePolicy(String name_, VolumesJBOD volumes_, double move_factor_) +StoragePolicy::StoragePolicy(String name_, Volumes volumes_, double move_factor_) : volumes(std::move(volumes_)), name(std::move(name_)), move_factor(move_factor_) { if (volumes.empty()) @@ -204,7 +204,7 @@ void StoragePolicy::checkCompatibleWith(const StoragePolicyPtr & new_storage_pol for (const auto & volume : getVolumes()) { if (new_volume_names.count(volume->getName()) == 0) - throw Exception("New storage policy shall contain volumes of old one", ErrorCodes::LOGICAL_ERROR); + throw Exception("New storage policy shall contain volumes of old one", ErrorCodes::BAD_ARGUMENTS); std::unordered_set new_disk_names; for (const auto & disk : new_storage_policy->getVolumeByName(volume->getName())->getDisks()) @@ -212,7 +212,7 @@ void StoragePolicy::checkCompatibleWith(const StoragePolicyPtr & new_storage_pol for (const auto & disk : volume->getDisks()) if (new_disk_names.count(disk->getName()) == 0) - throw Exception("New storage policy shall contain disks of old one", ErrorCodes::LOGICAL_ERROR); + throw Exception("New storage policy shall contain disks of old one", ErrorCodes::BAD_ARGUMENTS); } } @@ -257,7 +257,7 @@ StoragePolicySelector::StoragePolicySelector( { auto default_volume = std::make_shared(default_volume_name, std::vector{disks->get(default_disk_name)}, 0); - auto default_policy = std::make_shared(default_storage_policy_name, VolumesJBOD{default_volume}, 0.0); + auto default_policy = std::make_shared(default_storage_policy_name, Volumes{default_volume}, 0.0); policies.emplace(default_storage_policy_name, default_policy); } } diff --git a/src/Disks/StoragePolicy.h b/src/Disks/StoragePolicy.h index a8cba9abaeb..0e0795d8bf1 100644 --- a/src/Disks/StoragePolicy.h +++ b/src/Disks/StoragePolicy.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,7 @@ class StoragePolicy public: StoragePolicy(String name_, const Poco::Util::AbstractConfiguration & config, const String & config_prefix, DiskSelectorPtr disks); - StoragePolicy(String name_, VolumesJBOD volumes_, double move_factor_); + StoragePolicy(String name_, Volumes volumes_, double move_factor_); bool isDefaultPolicy() const; @@ -65,16 +66,16 @@ public: /// Do not use this function when it is possible to predict size. ReservationPtr makeEmptyReservationOnLargestDisk() const; - const VolumesJBOD & getVolumes() const { return volumes; } + const Volumes & getVolumes() const { return volumes; } /// Returns number [0., 1.] -- fraction of free space on disk /// which should be kept with help of background moves double getMoveFactor() const { return move_factor; } /// Get volume by index from storage_policy - VolumeJBODPtr getVolume(size_t i) const { return (i < volumes_names.size() ? volumes[i] : VolumeJBODPtr()); } + VolumePtr getVolume(size_t i) const { return (i < volumes_names.size() ? volumes[i] : VolumePtr()); } - VolumeJBODPtr getVolumeByName(const String & volume_name) const + VolumePtr getVolumeByName(const String & volume_name) const { auto it = volumes_names.find(volume_name); if (it == volumes_names.end()) @@ -86,7 +87,7 @@ public: void checkCompatibleWith(const StoragePolicyPtr & new_storage_policy) const; private: - VolumesJBOD volumes; + Volumes volumes; const String name; std::map volumes_names; diff --git a/src/Disks/VolumeJBOD.cpp b/src/Disks/VolumeJBOD.cpp index 7312f3d2365..bf9dcf7f5d8 100644 --- a/src/Disks/VolumeJBOD.cpp +++ b/src/Disks/VolumeJBOD.cpp @@ -17,8 +17,8 @@ VolumeJBOD::VolumeJBOD( String name_, const Poco::Util::AbstractConfiguration & config, const String & config_prefix, - DiskSelectorPtr disk_selector -) : IVolume(name_, config, config_prefix, disk_selector) + DiskSelectorPtr disk_selector) + : IVolume(name_, config, config_prefix, disk_selector) { Poco::Logger * logger = &Poco::Logger::get("StorageConfiguration"); @@ -55,7 +55,7 @@ VolumeJBOD::VolumeJBOD( LOG_WARNING(logger, "Volume {} max_data_part_size is too low ({} < {})", backQuote(name), ReadableSize(max_data_part_size), ReadableSize(MIN_PART_SIZE)); } -DiskPtr VolumeJBOD::getNextDisk() +DiskPtr VolumeJBOD::getDisk(size_t /* index */) const { size_t start_from = last_used.fetch_add(1u, std::memory_order_relaxed); size_t index = start_from % disks.size(); @@ -64,7 +64,8 @@ DiskPtr VolumeJBOD::getNextDisk() ReservationPtr VolumeJBOD::reserve(UInt64 bytes) { - /// This volume can not store files which size greater than max_data_part_size + /// This volume can not store data which size is greater than `max_data_part_size` + /// to ensure that parts of size greater than that go to another volume(s). if (max_data_part_size != 0 && bytes > max_data_part_size) return {}; diff --git a/src/Disks/VolumeJBOD.h b/src/Disks/VolumeJBOD.h index 16a96ec9fb9..52eb2f00721 100644 --- a/src/Disks/VolumeJBOD.h +++ b/src/Disks/VolumeJBOD.h @@ -14,7 +14,7 @@ class VolumeJBOD : public IVolume { public: VolumeJBOD(String name_, Disks disks_, UInt64 max_data_part_size_) - : IVolume(name_, disks_), max_data_part_size(max_data_part_size_) + : IVolume(name_, disks_, max_data_part_size_) { } @@ -27,19 +27,17 @@ public: VolumeType getType() const override { return VolumeType::JBOD; } - /// Next disk (round-robin) + /// Always returns next disk (round-robin), ignores argument. /// /// - Used with policy for temporary data /// - Ignores all limitations /// - Shares last access with reserve() - DiskPtr getNextDisk(); + DiskPtr getDisk(size_t index) const override; /// Uses Round-robin to choose disk for reservation. /// Returns valid reservation or nullptr if there is no space left on any disk. ReservationPtr reserve(UInt64 bytes) override; - /// Max size of reservation - UInt64 max_data_part_size = 0; private: mutable std::atomic last_used = 0; }; diff --git a/src/Disks/VolumeRAID1.cpp b/src/Disks/VolumeRAID1.cpp new file mode 100644 index 00000000000..d7696ab5d2f --- /dev/null +++ b/src/Disks/VolumeRAID1.cpp @@ -0,0 +1,29 @@ +#include "VolumeRAID1.h" + +#include +#include + +namespace DB +{ + +ReservationPtr VolumeRAID1::reserve(UInt64 bytes) +{ + /// This volume can not store data which size is greater than `max_data_part_size` + /// to ensure that parts of size greater than that go to another volume(s). + + if (max_data_part_size != 0 && bytes > max_data_part_size) + return {}; + + Reservations res(disks.size()); + for (size_t i = 0; i < disks.size(); ++i) + { + res[i] = disks[i]->reserve(bytes); + + if (!res[i]) + return {}; + } + + return std::make_unique(res, bytes); +} + +} diff --git a/src/Disks/VolumeRAID1.h b/src/Disks/VolumeRAID1.h new file mode 100644 index 00000000000..58cb5bd2623 --- /dev/null +++ b/src/Disks/VolumeRAID1.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +namespace DB +{ + +/// Volume which reserserves space on each underlying disk. +/// +/// NOTE: Just interface implementation, doesn't used in codebase, +/// also not available for user. +class VolumeRAID1 : public VolumeJBOD +{ +public: + VolumeRAID1(String name_, Disks disks_, UInt64 max_data_part_size_) + : VolumeJBOD(name_, disks_, max_data_part_size_) + { + } + + VolumeRAID1( + String name_, + const Poco::Util::AbstractConfiguration & config, + const String & config_prefix, + DiskSelectorPtr disk_selector) + : VolumeJBOD(name_, config, config_prefix, disk_selector) + { + } + + VolumeType getType() const override { return VolumeType::RAID1; } + + ReservationPtr reserve(UInt64 bytes) override; +}; + +using VolumeRAID1Ptr = std::shared_ptr; + +} diff --git a/src/Disks/createVolume.cpp b/src/Disks/createVolume.cpp index 071e3ec5aa6..90ed333406e 100644 --- a/src/Disks/createVolume.cpp +++ b/src/Disks/createVolume.cpp @@ -1,17 +1,53 @@ #include "createVolume.h" +#include +#include +#include + +#include + namespace DB { +namespace ErrorCodes +{ + extern const int UNKNOWN_RAID_TYPE; +} + VolumePtr createVolumeFromReservation(const ReservationPtr & reservation, VolumePtr other_volume) { if (other_volume->getType() == VolumeType::JBOD || other_volume->getType() == VolumeType::SINGLE_DISK) { - /// Since reservation on JBOD choices one of disks and makes reservation there, volume + /// Since reservation on JBOD chooses one of disks and makes reservation there, volume /// for such type of reservation will be with one disk. return std::make_shared(other_volume->getName(), reservation->getDisk()); } + if (other_volume->getType() == VolumeType::RAID1) + { + auto volume = std::dynamic_pointer_cast(other_volume); + return std::make_shared(volume->getName(), reservation->getDisks(), volume->max_data_part_size); + } return nullptr; } +VolumePtr createVolumeFromConfig( + String name, + const Poco::Util::AbstractConfiguration & config, + const String & config_prefix, + DiskSelectorPtr disk_selector +) +{ + auto has_raid_type = config.has(config_prefix + ".raid_type"); + if (!has_raid_type) + { + return std::make_shared(name, config, config_prefix, disk_selector); + } + String raid_type = config.getString(config_prefix + ".raid_type"); + if (raid_type == "JBOD") + { + return std::make_shared(name, config, config_prefix, disk_selector); + } + throw Exception("Unknown raid type '" + raid_type + "'", ErrorCodes::UNKNOWN_RAID_TYPE); +} + } diff --git a/src/Disks/createVolume.h b/src/Disks/createVolume.h index 52085ec16bc..64f5e73181b 100644 --- a/src/Disks/createVolume.h +++ b/src/Disks/createVolume.h @@ -1,12 +1,16 @@ #pragma once #include -#include -#include namespace DB { VolumePtr createVolumeFromReservation(const ReservationPtr & reservation, VolumePtr other_volume); +VolumePtr createVolumeFromConfig( + String name_, + const Poco::Util::AbstractConfiguration & config, + const String & config_prefix, + DiskSelectorPtr disk_selector +); } diff --git a/src/Disks/ya.make b/src/Disks/ya.make index 0187bd54b48..2c4aecd70ff 100644 --- a/src/Disks/ya.make +++ b/src/Disks/ya.make @@ -16,6 +16,7 @@ SRCS( SingleDiskVolume.cpp StoragePolicy.cpp VolumeJBOD.cpp + VolumeRAID1.cpp ) END() diff --git a/src/Formats/ProtobufColumnMatcher.cpp b/src/Formats/ProtobufColumnMatcher.cpp index ed9bd27bb34..f4803d1af10 100644 --- a/src/Formats/ProtobufColumnMatcher.cpp +++ b/src/Formats/ProtobufColumnMatcher.cpp @@ -1,7 +1,6 @@ #include "ProtobufColumnMatcher.h" #if USE_PROTOBUF #include -#include #include #include diff --git a/src/Formats/tests/tab_separated_streams.cpp b/src/Formats/tests/tab_separated_streams.cpp index 4071e453502..e39c7b6c920 100644 --- a/src/Formats/tests/tab_separated_streams.cpp +++ b/src/Formats/tests/tab_separated_streams.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include diff --git a/src/Functions/FunctionHelpers.cpp b/src/Functions/FunctionHelpers.cpp index b03abd4c1cf..18e5fde5462 100644 --- a/src/Functions/FunctionHelpers.cpp +++ b/src/Functions/FunctionHelpers.cpp @@ -8,7 +8,6 @@ #include #include #include -#include namespace DB diff --git a/src/Functions/FunctionsExternalModels.cpp b/src/Functions/FunctionsExternalModels.cpp index cf0d058c483..4fa04358525 100644 --- a/src/Functions/FunctionsExternalModels.cpp +++ b/src/Functions/FunctionsExternalModels.cpp @@ -4,8 +4,6 @@ #include #include -#include -#include #include #include #include diff --git a/src/Functions/addDays.cpp b/src/Functions/addDays.cpp index da85377323f..c86d7cfb2c1 100644 --- a/src/Functions/addDays.cpp +++ b/src/Functions/addDays.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/src/Functions/addHours.cpp b/src/Functions/addHours.cpp index 3052f7d0acd..cc526e6c8dc 100644 --- a/src/Functions/addHours.cpp +++ b/src/Functions/addHours.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/src/Functions/addMinutes.cpp b/src/Functions/addMinutes.cpp index 5c22059f792..b7920490a83 100644 --- a/src/Functions/addMinutes.cpp +++ b/src/Functions/addMinutes.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/src/Functions/addMonths.cpp b/src/Functions/addMonths.cpp index d2f44d4efbd..c74a8ecb08b 100644 --- a/src/Functions/addMonths.cpp +++ b/src/Functions/addMonths.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/src/Functions/addQuarters.cpp b/src/Functions/addQuarters.cpp index dd158186383..9b5e3556ff3 100644 --- a/src/Functions/addQuarters.cpp +++ b/src/Functions/addQuarters.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/src/Functions/addSeconds.cpp b/src/Functions/addSeconds.cpp index efc7129a62e..8ba229e238c 100644 --- a/src/Functions/addSeconds.cpp +++ b/src/Functions/addSeconds.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/src/Functions/addWeeks.cpp b/src/Functions/addWeeks.cpp index 050091c0b74..2b83f61f45c 100644 --- a/src/Functions/addWeeks.cpp +++ b/src/Functions/addWeeks.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/src/Functions/addYears.cpp b/src/Functions/addYears.cpp index f47e13a144b..24364154c23 100644 --- a/src/Functions/addYears.cpp +++ b/src/Functions/addYears.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/src/Functions/addressToLine.cpp b/src/Functions/addressToLine.cpp index 4631fb7a283..b5a6fcfb30e 100644 --- a/src/Functions/addressToLine.cpp +++ b/src/Functions/addressToLine.cpp @@ -1,6 +1,5 @@ #if defined(__ELF__) && !defined(__FreeBSD__) -#include #include #include #include @@ -9,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/src/Functions/addressToSymbol.cpp b/src/Functions/addressToSymbol.cpp index edd7a8a3ec6..077b4f9a80b 100644 --- a/src/Functions/addressToSymbol.cpp +++ b/src/Functions/addressToSymbol.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/src/Functions/assumeNotNull.cpp b/src/Functions/assumeNotNull.cpp index 67e42ec49a9..e2b543d1be8 100644 --- a/src/Functions/assumeNotNull.cpp +++ b/src/Functions/assumeNotNull.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/src/Functions/bar.cpp b/src/Functions/bar.cpp index 67d5aef9cb3..a80cddfb5e3 100644 --- a/src/Functions/bar.cpp +++ b/src/Functions/bar.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/src/Functions/concat.cpp b/src/Functions/concat.cpp index d87d7a5a8e6..12ab2d208a7 100644 --- a/src/Functions/concat.cpp +++ b/src/Functions/concat.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/src/Functions/demange.cpp b/src/Functions/demange.cpp index d6674378aa8..db525c4d0d1 100644 --- a/src/Functions/demange.cpp +++ b/src/Functions/demange.cpp @@ -1,9 +1,7 @@ #include #include -#include #include #include -#include #include #include #include diff --git a/src/Functions/equals.cpp b/src/Functions/equals.cpp index 30c9f3fe707..9d1244d6bd0 100644 --- a/src/Functions/equals.cpp +++ b/src/Functions/equals.cpp @@ -1,6 +1,5 @@ #include #include -#include namespace DB diff --git a/src/Functions/evalMLMethod.cpp b/src/Functions/evalMLMethod.cpp index c435299a152..f4c8ecf1c2b 100644 --- a/src/Functions/evalMLMethod.cpp +++ b/src/Functions/evalMLMethod.cpp @@ -2,16 +2,12 @@ #include #include #include -#include #include #include -#include -#include #include #include -#include namespace DB { diff --git a/src/Functions/extractGroups.cpp b/src/Functions/extractGroups.cpp index f153f7e0699..2146f8d72b9 100644 --- a/src/Functions/extractGroups.cpp +++ b/src/Functions/extractGroups.cpp @@ -9,7 +9,6 @@ #include #include -#include namespace DB diff --git a/src/Functions/fuzzBits.cpp b/src/Functions/fuzzBits.cpp index e030d12c071..c5ef448e7f0 100644 --- a/src/Functions/fuzzBits.cpp +++ b/src/Functions/fuzzBits.cpp @@ -5,12 +5,9 @@ #include #include #include -#include #include #include -#include - #include namespace DB diff --git a/src/Functions/geoToH3.cpp b/src/Functions/geoToH3.cpp index abefac858ce..924cdf68cb9 100644 --- a/src/Functions/geoToH3.cpp +++ b/src/Functions/geoToH3.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/src/Functions/geohashDecode.cpp b/src/Functions/geohashDecode.cpp index d08dc95f735..f8e57d0feb1 100644 --- a/src/Functions/geohashDecode.cpp +++ b/src/Functions/geohashDecode.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/src/Functions/isZeroOrNull.cpp b/src/Functions/isZeroOrNull.cpp index fd2e5277f51..02d97181016 100644 --- a/src/Functions/isZeroOrNull.cpp +++ b/src/Functions/isZeroOrNull.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/src/Functions/tests/CMakeLists.txt b/src/Functions/tests/CMakeLists.txt index 7aed80c2da7..e69de29bb2d 100644 --- a/src/Functions/tests/CMakeLists.txt +++ b/src/Functions/tests/CMakeLists.txt @@ -1,4 +0,0 @@ -add_executable (number_traits number_traits.cpp) -add_executable (abtesting abtesting.cpp) -target_link_libraries (number_traits PRIVATE dbms) -target_link_libraries (abtesting PRIVATE clickhouse_functions) diff --git a/src/Functions/tests/abtesting.cpp b/src/Functions/tests/gtest_abtesting.cpp similarity index 85% rename from src/Functions/tests/abtesting.cpp rename to src/Functions/tests/gtest_abtesting.cpp index 3ac57042db4..0e0234e0096 100644 --- a/src/Functions/tests/abtesting.cpp +++ b/src/Functions/tests/gtest_abtesting.cpp @@ -1,3 +1,5 @@ +#include + #include #include #include @@ -61,34 +63,37 @@ Variants test_bayesab(std::string dist, PODArray xs, PODArray } -int main(int, char **) +TEST(BayesAB, beta) { size_t max = 0, min = 0; auto variants = test_bayesab("beta", {10000, 1000, 900}, {600, 110, 90}, max, min); - if (max != 1) exit(1); + ASSERT_EQ(1, max); variants = test_bayesab("beta", {3000, 3000, 3000}, {600, 100, 90}, max, min); - if (max != 0) exit(1); + ASSERT_EQ(0, max); variants = test_bayesab("beta", {3000, 3000, 3000}, {100, 90, 110}, max, min); - if (max != 2) exit(1); + ASSERT_EQ(2, max); variants = test_bayesab("beta", {3000, 3000, 3000}, {110, 90, 100}, max, min); - if (max != 0) exit(1); + ASSERT_EQ(0, max); +} - variants = test_bayesab("gamma", {10000, 1000, 900}, {600, 110, 90}, max, min); - if (max != 1) exit(1); + +TEST(BayesAB, gamma) +{ + size_t max = 0, min = 0; + auto variants = test_bayesab("gamma", {10000, 1000, 900}, {600, 110, 90}, max, min); + ASSERT_EQ(1, max); variants = test_bayesab("gamma", {3000, 3000, 3000}, {600, 100, 90}, max, min); - if (max != 0) exit(1); + ASSERT_EQ(0, max); variants = test_bayesab("gamma", {3000, 3000, 3000}, {100, 90, 110}, max, min); - if (max != 2) exit(1); + ASSERT_EQ(2, max); variants = test_bayesab("gamma", {3000, 3000, 3000}, {110, 90, 100}, max, min); - if (max != 0) exit(1); - - std::cout << "Successfully done\n"; - return 0; + ASSERT_EQ(0, max); } + diff --git a/src/Functions/tests/gtest_number_traits.cpp b/src/Functions/tests/gtest_number_traits.cpp new file mode 100644 index 00000000000..7199b269190 --- /dev/null +++ b/src/Functions/tests/gtest_number_traits.cpp @@ -0,0 +1,201 @@ +#include + +#include +#include + +#include + +static const std::map, std::string> answer = +{ + {{"UInt8", "UInt8"}, "UInt8"}, + {{"UInt8", "UInt16"}, "UInt16"}, + {{"UInt8", "UInt32"}, "UInt32"}, + {{"UInt8", "UInt64"}, "UInt64"}, + {{"UInt8", "Int8"}, "Int16"}, + {{"UInt8", "Int16"}, "Int16"}, + {{"UInt8", "Int32"}, "Int32"}, + {{"UInt8", "Int64"}, "Int64"}, + {{"UInt8", "Float32"}, "Float32"}, + {{"UInt8", "Float64"}, "Float64"}, + {{"UInt16", "UInt8"}, "UInt16"}, + {{"UInt16", "UInt16"}, "UInt16"}, + {{"UInt16", "UInt32"}, "UInt32"}, + {{"UInt16", "UInt64"}, "UInt64"}, + {{"UInt16", "Int8"}, "Int32"}, + {{"UInt16", "Int16"}, "Int32"}, + {{"UInt16", "Int32"}, "Int32"}, + {{"UInt16", "Int64"}, "Int64"}, + {{"UInt16", "Float32"}, "Float32"}, + {{"UInt16", "Float64"}, "Float64"}, + {{"UInt32", "UInt8"}, "UInt32"}, + {{"UInt32", "UInt16"}, "UInt32"}, + {{"UInt32", "UInt32"}, "UInt32"}, + {{"UInt32", "UInt64"}, "UInt64"}, + {{"UInt32", "Int8"}, "Int64"}, + {{"UInt32", "Int16"}, "Int64"}, + {{"UInt32", "Int32"}, "Int64"}, + {{"UInt32", "Int64"}, "Int64"}, + {{"UInt32", "Float32"}, "Float64"}, + {{"UInt32", "Float64"}, "Float64"}, + {{"UInt64", "UInt8"}, "UInt64"}, + {{"UInt64", "UInt16"}, "UInt64"}, + {{"UInt64", "UInt32"}, "UInt64"}, + {{"UInt64", "UInt64"}, "UInt64"}, + {{"UInt64", "Int8"}, "Error"}, + {{"UInt64", "Int16"}, "Error"}, + {{"UInt64", "Int32"}, "Error"}, + {{"UInt64", "Int64"}, "Error"}, + {{"UInt64", "Float32"}, "Error"}, + {{"UInt64", "Float64"}, "Error"}, + {{"Int8", "UInt8"}, "Int16"}, + {{"Int8", "UInt16"}, "Int32"}, + {{"Int8", "UInt32"}, "Int64"}, + {{"Int8", "UInt64"}, "Error"}, + {{"Int8", "Int8"}, "Int8"}, + {{"Int8", "Int16"}, "Int16"}, + {{"Int8", "Int32"}, "Int32"}, + {{"Int8", "Int64"}, "Int64"}, + {{"Int8", "Float32"}, "Float32"}, + {{"Int8", "Float64"}, "Float64"}, + {{"Int16", "UInt8"}, "Int16"}, + {{"Int16", "UInt16"}, "Int32"}, + {{"Int16", "UInt32"}, "Int64"}, + {{"Int16", "UInt64"}, "Error"}, + {{"Int16", "Int8"}, "Int16"}, + {{"Int16", "Int16"}, "Int16"}, + {{"Int16", "Int32"}, "Int32"}, + {{"Int16", "Int64"}, "Int64"}, + {{"Int16", "Float32"}, "Float32"}, + {{"Int16", "Float64"}, "Float64"}, + {{"Int32", "UInt8"}, "Int32"}, + {{"Int32", "UInt16"}, "Int32"}, + {{"Int32", "UInt32"}, "Int64"}, + {{"Int32", "UInt64"}, "Error"}, + {{"Int32", "Int8"}, "Int32"}, + {{"Int32", "Int16"}, "Int32"}, + {{"Int32", "Int32"}, "Int32"}, + {{"Int32", "Int64"}, "Int64"}, + {{"Int32", "Float32"}, "Float64"}, + {{"Int32", "Float64"}, "Float64"}, + {{"Int64", "UInt8"}, "Int64"}, + {{"Int64", "UInt16"}, "Int64"}, + {{"Int64", "UInt32"}, "Int64"}, + {{"Int64", "UInt64"}, "Error"}, + {{"Int64", "Int8"}, "Int64"}, + {{"Int64", "Int16"}, "Int64"}, + {{"Int64", "Int32"}, "Int64"}, + {{"Int64", "Int64"}, "Int64"}, + {{"Int64", "Float32"}, "Error"}, + {{"Int64", "Float64"}, "Error"}, + {{"Float32", "UInt8"}, "Float32"}, + {{"Float32", "UInt16"}, "Float32"}, + {{"Float32", "UInt32"}, "Float64"}, + {{"Float32", "UInt64"}, "Error"}, + {{"Float32", "Int8"}, "Float32"}, + {{"Float32", "Int16"}, "Float32"}, + {{"Float32", "Int32"}, "Float64"}, + {{"Float32", "Int64"}, "Error"}, + {{"Float32", "Float32"}, "Float32"}, + {{"Float32", "Float64"}, "Float64"}, + {{"Float64", "UInt8"}, "Float64"}, + {{"Float64", "UInt16"}, "Float64"}, + {{"Float64", "UInt32"}, "Float64"}, + {{"Float64", "UInt64"}, "Error"}, + {{"Float64", "Int8"}, "Float64"}, + {{"Float64", "Int16"}, "Float64"}, + {{"Float64", "Int32"}, "Float64"}, + {{"Float64", "Int64"}, "Error"}, + {{"Float64", "Float32"}, "Float64"}, + {{"Float64", "Float64"}, "Float64"} +}; + +static std::string getTypeString(DB::UInt8) { return "UInt8"; } +static std::string getTypeString(DB::UInt16) { return "UInt16"; } +static std::string getTypeString(DB::UInt32) { return "UInt32"; } +static std::string getTypeString(DB::UInt64) { return "UInt64"; } +static std::string getTypeString(DB::Int8) { return "Int8"; } +static std::string getTypeString(DB::Int16) { return "Int16"; } +static std::string getTypeString(DB::Int32) { return "Int32"; } +static std::string getTypeString(DB::Int64) { return "Int64"; } +static std::string getTypeString(DB::Float32) { return "Float32"; } +static std::string getTypeString(DB::Float64) { return "Float64"; } +static std::string getTypeString(DB::NumberTraits::Error) { return "Error"; } + +template +[[maybe_unused]] void printTypes() +{ + std::cout << "{{\""; + std::cout << getTypeString(T0()); + std::cout << "\", \""; + std::cout << getTypeString(T1()); + std::cout << "\"}, \""; + std::cout << getTypeString(typename DB::NumberTraits::ResultOfIf::Type()); + std::cout << "\"},"<< std::endl; +} + +template +void ifRightType() +{ + auto desired = getTypeString(typename DB::NumberTraits::ResultOfIf::Type()); + auto left = getTypeString(T0()); + auto right = getTypeString(T1()); + auto expected = answer.find({left, right}); + ASSERT_TRUE(expected != answer.end()); + ASSERT_EQ(expected->second, desired); +} + +template +void ifLeftType() +{ + ifRightType(); + ifRightType(); + ifRightType(); + ifRightType(); + ifRightType(); + ifRightType(); + ifRightType(); + ifRightType(); + ifRightType(); + ifRightType(); +} + + +TEST(NumberTraits, ResultOfAdditionMultiplication) +{ + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfAdditionMultiplication::Type()), "UInt16"); + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfAdditionMultiplication::Type()), "Int64"); + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfAdditionMultiplication::Type()), "Float64"); +} + + +TEST(NumberTraits, ResultOfSubtraction) +{ + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfSubtraction::Type()), "Int16"); + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfSubtraction::Type()), "Int32"); + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfSubtraction::Type()), "Int32"); +} + + +TEST(NumberTraits, Others) +{ + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfFloatingPointDivision::Type()), "Float64"); + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfFloatingPointDivision::Type()), "Float64"); + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfIntegerDivision::Type()), "Int8"); + ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfModulo::Type()), "Int8"); +} + + +TEST(NumberTraits, FunctionIf) +{ + ifLeftType(); + ifLeftType(); + ifLeftType(); + ifLeftType(); + ifLeftType(); + ifLeftType(); + ifLeftType(); + ifLeftType(); + ifLeftType(); + ifLeftType(); +} + diff --git a/src/Functions/tests/number_traits.cpp b/src/Functions/tests/number_traits.cpp deleted file mode 100644 index f32ffd5ea97..00000000000 --- a/src/Functions/tests/number_traits.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include - -#include - - -static void printType(DB::UInt8) { std::cout << "UInt8"; } -static void printType(DB::UInt16) { std::cout << "UInt16"; } -static void printType(DB::UInt32) { std::cout << "UInt32"; } -static void printType(DB::UInt64) { std::cout << "UInt64"; } -static void printType(DB::Int8) { std::cout << "Int8"; } -static void printType(DB::Int16) { std::cout << "Int16"; } -static void printType(DB::Int32) { std::cout << "Int32"; } -static void printType(DB::Int64) { std::cout << "Int64"; } -static void printType(DB::Float32) { std::cout << "Float32"; } -static void printType(DB::Float64) { std::cout << "Float64"; } -static void printType(DB::NumberTraits::Error) { std::cout << "Error"; } - -template -void ifRightType() -{ - printType(T0()); - std::cout << ", "; - printType(T1()); - std::cout << " -> "; - printType(typename DB::NumberTraits::ResultOfIf::Type()); - std::cout << std::endl; -} - -template -void ifLeftType() -{ - ifRightType(); - ifRightType(); - ifRightType(); - ifRightType(); - ifRightType(); - ifRightType(); - ifRightType(); - ifRightType(); - ifRightType(); - ifRightType(); -} - -int main(int, char **) -{ - printType(DB::NumberTraits::ResultOfAdditionMultiplication::Type()); std::cout << std::endl; - printType(DB::NumberTraits::ResultOfAdditionMultiplication::Type()); std::cout << std::endl; - printType(DB::NumberTraits::ResultOfAdditionMultiplication::Type()); std::cout << std::endl; - printType(DB::NumberTraits::ResultOfSubtraction::Type()); std::cout << std::endl; - printType(DB::NumberTraits::ResultOfSubtraction::Type()); std::cout << std::endl; - printType(DB::NumberTraits::ResultOfSubtraction::Type()); std::cout << std::endl; - printType(DB::NumberTraits::ResultOfFloatingPointDivision::Type()); std::cout << std::endl; - printType(DB::NumberTraits::ResultOfFloatingPointDivision::Type()); std::cout << std::endl; - printType(DB::NumberTraits::ResultOfIntegerDivision::Type()); std::cout << std::endl; - printType(DB::NumberTraits::ResultOfModulo::Type()); std::cout << std::endl; - - ifLeftType(); - ifLeftType(); - ifLeftType(); - ifLeftType(); - ifLeftType(); - ifLeftType(); - ifLeftType(); - ifLeftType(); - ifLeftType(); - ifLeftType(); - - return 0; -} diff --git a/src/Functions/toDayOfMonth.cpp b/src/Functions/toDayOfMonth.cpp index 7446e856a05..0f6d2ad6a46 100644 --- a/src/Functions/toDayOfMonth.cpp +++ b/src/Functions/toDayOfMonth.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toDayOfWeek.cpp b/src/Functions/toDayOfWeek.cpp index 90dabb7223d..71303489321 100644 --- a/src/Functions/toDayOfWeek.cpp +++ b/src/Functions/toDayOfWeek.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toDayOfYear.cpp b/src/Functions/toDayOfYear.cpp index 77707bed9fa..301232040b7 100644 --- a/src/Functions/toDayOfYear.cpp +++ b/src/Functions/toDayOfYear.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toHour.cpp b/src/Functions/toHour.cpp index 99dbac15505..fb973a9b4b8 100644 --- a/src/Functions/toHour.cpp +++ b/src/Functions/toHour.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toISOWeek.cpp b/src/Functions/toISOWeek.cpp index 182f9bba2f6..9cdee8b7a94 100644 --- a/src/Functions/toISOWeek.cpp +++ b/src/Functions/toISOWeek.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toISOYear.cpp b/src/Functions/toISOYear.cpp index c90b043133a..200ce7aa97e 100644 --- a/src/Functions/toISOYear.cpp +++ b/src/Functions/toISOYear.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toLowCardinality.cpp b/src/Functions/toLowCardinality.cpp index f7f29050be4..8f0dfd2e932 100644 --- a/src/Functions/toLowCardinality.cpp +++ b/src/Functions/toLowCardinality.cpp @@ -1,8 +1,6 @@ #include #include -#include #include -#include #include #include diff --git a/src/Functions/toMinute.cpp b/src/Functions/toMinute.cpp index fb8c5b7477f..a928925156e 100644 --- a/src/Functions/toMinute.cpp +++ b/src/Functions/toMinute.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toMonday.cpp b/src/Functions/toMonday.cpp index 4a9d2987278..02a1d65b309 100644 --- a/src/Functions/toMonday.cpp +++ b/src/Functions/toMonday.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toMonth.cpp b/src/Functions/toMonth.cpp index 07f8b5ef4fe..91ac349d9a1 100644 --- a/src/Functions/toMonth.cpp +++ b/src/Functions/toMonth.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toNullable.cpp b/src/Functions/toNullable.cpp index ac21489bfe0..8be5f3ad243 100644 --- a/src/Functions/toNullable.cpp +++ b/src/Functions/toNullable.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/src/Functions/toQuarter.cpp b/src/Functions/toQuarter.cpp index 22ac62bdddd..f046c3abe46 100644 --- a/src/Functions/toQuarter.cpp +++ b/src/Functions/toQuarter.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toRelativeDayNum.cpp b/src/Functions/toRelativeDayNum.cpp index e02e9cd15fa..7b4ca094843 100644 --- a/src/Functions/toRelativeDayNum.cpp +++ b/src/Functions/toRelativeDayNum.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toRelativeHourNum.cpp b/src/Functions/toRelativeHourNum.cpp index 687784de6d9..e49906c8d56 100644 --- a/src/Functions/toRelativeHourNum.cpp +++ b/src/Functions/toRelativeHourNum.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toRelativeMinuteNum.cpp b/src/Functions/toRelativeMinuteNum.cpp index 86221fd6d0b..5e2b737a814 100644 --- a/src/Functions/toRelativeMinuteNum.cpp +++ b/src/Functions/toRelativeMinuteNum.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toRelativeMonthNum.cpp b/src/Functions/toRelativeMonthNum.cpp index a6b09b3d57e..695ed89ec18 100644 --- a/src/Functions/toRelativeMonthNum.cpp +++ b/src/Functions/toRelativeMonthNum.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toRelativeQuarterNum.cpp b/src/Functions/toRelativeQuarterNum.cpp index ebf510b62e2..fdd5ed57c89 100644 --- a/src/Functions/toRelativeQuarterNum.cpp +++ b/src/Functions/toRelativeQuarterNum.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toRelativeSecondNum.cpp b/src/Functions/toRelativeSecondNum.cpp index 87bba4eb207..02b63d86133 100644 --- a/src/Functions/toRelativeSecondNum.cpp +++ b/src/Functions/toRelativeSecondNum.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toRelativeWeekNum.cpp b/src/Functions/toRelativeWeekNum.cpp index 8b9234c6aaa..b0c4aa730fb 100644 --- a/src/Functions/toRelativeWeekNum.cpp +++ b/src/Functions/toRelativeWeekNum.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toRelativeYearNum.cpp b/src/Functions/toRelativeYearNum.cpp index de2713ea25f..94717a8abb3 100644 --- a/src/Functions/toRelativeYearNum.cpp +++ b/src/Functions/toRelativeYearNum.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toSecond.cpp b/src/Functions/toSecond.cpp index 934c42562db..90196cc6722 100644 --- a/src/Functions/toSecond.cpp +++ b/src/Functions/toSecond.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toStartOfDay.cpp b/src/Functions/toStartOfDay.cpp index 5ecd01f1f6e..a9632733d9b 100644 --- a/src/Functions/toStartOfDay.cpp +++ b/src/Functions/toStartOfDay.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfFifteenMinutes.cpp b/src/Functions/toStartOfFifteenMinutes.cpp index 3189d640ea2..ceac5702915 100644 --- a/src/Functions/toStartOfFifteenMinutes.cpp +++ b/src/Functions/toStartOfFifteenMinutes.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfFiveMinute.cpp b/src/Functions/toStartOfFiveMinute.cpp index 32d6be3d957..c154b8f2bc7 100644 --- a/src/Functions/toStartOfFiveMinute.cpp +++ b/src/Functions/toStartOfFiveMinute.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfHour.cpp b/src/Functions/toStartOfHour.cpp index 198345a299a..a2273f2e78f 100644 --- a/src/Functions/toStartOfHour.cpp +++ b/src/Functions/toStartOfHour.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfISOYear.cpp b/src/Functions/toStartOfISOYear.cpp index 68347e33daf..a9b338a0a82 100644 --- a/src/Functions/toStartOfISOYear.cpp +++ b/src/Functions/toStartOfISOYear.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfMinute.cpp b/src/Functions/toStartOfMinute.cpp index e81123ef7b9..5fa7fc8ab4b 100644 --- a/src/Functions/toStartOfMinute.cpp +++ b/src/Functions/toStartOfMinute.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfMonth.cpp b/src/Functions/toStartOfMonth.cpp index 8618bee747e..8bad02acc81 100644 --- a/src/Functions/toStartOfMonth.cpp +++ b/src/Functions/toStartOfMonth.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfQuarter.cpp b/src/Functions/toStartOfQuarter.cpp index ef7c6a653f8..c2d2697e86c 100644 --- a/src/Functions/toStartOfQuarter.cpp +++ b/src/Functions/toStartOfQuarter.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfSecond.cpp b/src/Functions/toStartOfSecond.cpp index f796dce410a..d4197a36e6c 100644 --- a/src/Functions/toStartOfSecond.cpp +++ b/src/Functions/toStartOfSecond.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfTenMinutes.cpp b/src/Functions/toStartOfTenMinutes.cpp index 86bd6df8bf8..8cff4cc13cd 100644 --- a/src/Functions/toStartOfTenMinutes.cpp +++ b/src/Functions/toStartOfTenMinutes.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toStartOfYear.cpp b/src/Functions/toStartOfYear.cpp index e52d90ec9a6..cef10c1534d 100644 --- a/src/Functions/toStartOfYear.cpp +++ b/src/Functions/toStartOfYear.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toTime.cpp b/src/Functions/toTime.cpp index bfc5034edf0..b7ff56a18c4 100644 --- a/src/Functions/toTime.cpp +++ b/src/Functions/toTime.cpp @@ -1,8 +1,6 @@ -#include #include #include #include -#include namespace DB diff --git a/src/Functions/toTimeZone.cpp b/src/Functions/toTimeZone.cpp index b06eeb520a4..d75b202ed41 100644 --- a/src/Functions/toTimeZone.cpp +++ b/src/Functions/toTimeZone.cpp @@ -1,8 +1,6 @@ #include #include -#include - #include #include #include diff --git a/src/Functions/toValidUTF8.cpp b/src/Functions/toValidUTF8.cpp index e7add23fb07..c18ef8e7622 100644 --- a/src/Functions/toValidUTF8.cpp +++ b/src/Functions/toValidUTF8.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include diff --git a/src/Functions/toYYYYMM.cpp b/src/Functions/toYYYYMM.cpp index 4475cfde2b1..3dfefc4adb1 100644 --- a/src/Functions/toYYYYMM.cpp +++ b/src/Functions/toYYYYMM.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toYYYYMMDD.cpp b/src/Functions/toYYYYMMDD.cpp index f7a159626a9..fa5e85341fd 100644 --- a/src/Functions/toYYYYMMDD.cpp +++ b/src/Functions/toYYYYMMDD.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toYYYYMMDDhhmmss.cpp b/src/Functions/toYYYYMMDDhhmmss.cpp index e0326ada8e7..7718bbab763 100644 --- a/src/Functions/toYYYYMMDDhhmmss.cpp +++ b/src/Functions/toYYYYMMDDhhmmss.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/toYear.cpp b/src/Functions/toYear.cpp index 2f74a3a9cd2..870582e2ccd 100644 --- a/src/Functions/toYear.cpp +++ b/src/Functions/toYear.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/transform.cpp b/src/Functions/transform.cpp index 5893e8666db..884b972c2b4 100644 --- a/src/Functions/transform.cpp +++ b/src/Functions/transform.cpp @@ -1,7 +1,5 @@ #include #include -#include -#include #include #include #include diff --git a/src/Functions/upper.cpp b/src/Functions/upper.cpp index e111827a87f..e96a5a312fb 100644 --- a/src/Functions/upper.cpp +++ b/src/Functions/upper.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/Functions/upperUTF8.cpp b/src/Functions/upperUTF8.cpp index 048eb7b60c9..a6c7a4d41cd 100644 --- a/src/Functions/upperUTF8.cpp +++ b/src/Functions/upperUTF8.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/IO/tests/gtest_bit_io.cpp b/src/IO/tests/gtest_bit_io.cpp index 98539ea85a3..437ec13e93c 100644 --- a/src/IO/tests/gtest_bit_io.cpp +++ b/src/IO/tests/gtest_bit_io.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include diff --git a/src/IO/tests/gtest_cascade_and_memory_write_buffer.cpp b/src/IO/tests/gtest_cascade_and_memory_write_buffer.cpp index 2c90fad3106..4936307a5e3 100644 --- a/src/IO/tests/gtest_cascade_and_memory_write_buffer.cpp +++ b/src/IO/tests/gtest_cascade_and_memory_write_buffer.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/src/IO/tests/parse_int_perf.cpp b/src/IO/tests/parse_int_perf.cpp index 266dee96fb6..93f49d80258 100644 --- a/src/IO/tests/parse_int_perf.cpp +++ b/src/IO/tests/parse_int_perf.cpp @@ -7,9 +7,6 @@ #include #include #include -#include -#include -#include #include #include diff --git a/src/IO/tests/read_buffer.cpp b/src/IO/tests/read_buffer.cpp index 08c5fd563fa..952f8136a63 100644 --- a/src/IO/tests/read_buffer.cpp +++ b/src/IO/tests/read_buffer.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include diff --git a/src/IO/tests/read_buffer_perf.cpp b/src/IO/tests/read_buffer_perf.cpp index 8269858ac64..74520a63041 100644 --- a/src/IO/tests/read_buffer_perf.cpp +++ b/src/IO/tests/read_buffer_perf.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include diff --git a/src/IO/tests/read_escaped_string.cpp b/src/IO/tests/read_escaped_string.cpp index 55f18c29c81..db99e094c06 100644 --- a/src/IO/tests/read_escaped_string.cpp +++ b/src/IO/tests/read_escaped_string.cpp @@ -2,7 +2,6 @@ #include -#include #include #include #include diff --git a/src/IO/tests/read_write_int.cpp b/src/IO/tests/read_write_int.cpp index 52b21ee7de6..903940db5e4 100644 --- a/src/IO/tests/read_write_int.cpp +++ b/src/IO/tests/read_write_int.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include diff --git a/src/IO/tests/valid_utf8.cpp b/src/IO/tests/valid_utf8.cpp index 0174f76f7d8..070a0a4c116 100644 --- a/src/IO/tests/valid_utf8.cpp +++ b/src/IO/tests/valid_utf8.cpp @@ -1,11 +1,8 @@ #include #include -#include #include #include -#include #include -#include int main(int, char **) { diff --git a/src/IO/tests/valid_utf8_perf.cpp b/src/IO/tests/valid_utf8_perf.cpp index ce9edcbb382..b95cdb2c27c 100644 --- a/src/IO/tests/valid_utf8_perf.cpp +++ b/src/IO/tests/valid_utf8_perf.cpp @@ -2,9 +2,7 @@ #include #include #include -#include #include -#include int main(int argc, char ** argv) { diff --git a/src/IO/tests/write_buffer.cpp b/src/IO/tests/write_buffer.cpp index feb9e5903ae..8737f29cffb 100644 --- a/src/IO/tests/write_buffer.cpp +++ b/src/IO/tests/write_buffer.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include diff --git a/src/IO/tests/zlib_buffers.cpp b/src/IO/tests/zlib_buffers.cpp index 3c7af125a5a..3428d5e995a 100644 --- a/src/IO/tests/zlib_buffers.cpp +++ b/src/IO/tests/zlib_buffers.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/src/Interpreters/ActionsVisitor.cpp b/src/Interpreters/ActionsVisitor.cpp index f7abfe8950c..6e10b66622f 100644 --- a/src/Interpreters/ActionsVisitor.cpp +++ b/src/Interpreters/ActionsVisitor.cpp @@ -64,6 +64,17 @@ static NamesAndTypesList::iterator findColumn(const String & name, NamesAndTypes [&](const NamesAndTypesList::value_type & val) { return val.name == name; }); } +/// Recursion is limited in query parser and we did not check for too large depth here. +static size_t getTypeDepth(const DataTypePtr & type) +{ + if (const auto * array_type = typeid_cast(type.get())) + return 1 + getTypeDepth(array_type->getNestedType()); + else if (const auto * tuple_type = typeid_cast(type.get())) + return 1 + (tuple_type->getElements().empty() ? 0 : getTypeDepth(tuple_type->getElements().at(0))); + + return 0; +} + template static Block createBlockFromCollection(const Collection & collection, const DataTypes & types, const Context & context) { @@ -117,48 +128,119 @@ static Block createBlockFromCollection(const Collection & collection, const Data return res; } -SetPtr makeExplicitSet( - const ASTFunction * node, const Block & sample_block, bool create_ordered_set, - const Context & context, const SizeLimits & size_limits, PreparedSets & prepared_sets) +static Field extractValueFromNode(const ASTPtr & node, const IDataType & type, const Context & context) { - const IAST & args = *node->arguments; + if (const auto * lit = node->as()) + { + return convertFieldToType(lit->value, type); + } + else if (node->as()) + { + std::pair value_raw = evaluateConstantExpression(node, context); + return convertFieldToType(value_raw.first, type, value_raw.second.get()); + } + else + throw Exception("Incorrect element of set. Must be literal or constant expression.", ErrorCodes::INCORRECT_ELEMENT_OF_SET); +} - if (args.children.size() != 2) - throw Exception("Wrong number of arguments passed to function in", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); +static Block createBlockFromAST(const ASTPtr & node, const DataTypes & types, const Context & context) +{ + /// Will form a block with values from the set. - const ASTPtr & left_arg = args.children.at(0); - const ASTPtr & right_arg = args.children.at(1); + Block header; + size_t num_columns = types.size(); + for (size_t i = 0; i < num_columns; ++i) + header.insert(ColumnWithTypeAndName(types[i]->createColumn(), types[i], "_" + toString(i))); - const DataTypePtr & left_arg_type = sample_block.getByName(left_arg->getColumnName()).type; + MutableColumns columns = header.cloneEmptyColumns(); - DataTypes set_element_types = {left_arg_type}; - const auto * left_tuple_type = typeid_cast(left_arg_type.get()); - if (left_tuple_type && left_tuple_type->getElements().size() != 1) - set_element_types = left_tuple_type->getElements(); + DataTypePtr tuple_type; + Row tuple_values; + const auto & list = node->as(); + for (const auto & elem : list.children) + { + if (num_columns == 1) + { + Field value = extractValueFromNode(elem, *types[0], context); - for (auto & element_type : set_element_types) - if (const auto * low_cardinality_type = typeid_cast(element_type.get())) - element_type = low_cardinality_type->getDictionaryType(); + if (!value.isNull() || context.getSettingsRef().transform_null_in) + columns[0]->insert(value); + } + else if (elem->as() || elem->as()) + { + Field function_result; + const Tuple * tuple = nullptr; - auto set_key = PreparedSetKey::forLiteral(*right_arg, set_element_types); - if (prepared_sets.count(set_key)) - return prepared_sets.at(set_key); /// Already prepared. + auto * func = elem->as(); + if (func && func->name != "tuple") + { + if (!tuple_type) + tuple_type = std::make_shared(types); + function_result = extractValueFromNode(elem, *tuple_type, context); + if (function_result.getType() != Field::Types::Tuple) + throw Exception("Invalid type of set. Expected tuple, got " + String(function_result.getTypeName()), + ErrorCodes::INCORRECT_ELEMENT_OF_SET); + + tuple = &function_result.get(); + } + + auto * literal = elem->as(); + if (literal) + { + if (literal->value.getType() != Field::Types::Tuple) + throw Exception("Invalid type in set. Expected tuple, got " + + String(literal->value.getTypeName()), ErrorCodes::INCORRECT_ELEMENT_OF_SET); + + tuple = &literal->value.get(); + } + + size_t tuple_size = tuple ? tuple->size() : func->arguments->children.size(); + if (tuple_size != num_columns) + throw Exception("Incorrect size of tuple in set: " + toString(tuple_size) + " instead of " + toString(num_columns), + ErrorCodes::INCORRECT_ELEMENT_OF_SET); + + if (tuple_values.empty()) + tuple_values.resize(tuple_size); + + size_t i = 0; + for (; i < tuple_size; ++i) + { + Field value = tuple ? (*tuple)[i] + : extractValueFromNode(func->arguments->children[i], *types[i], context); + + /// If at least one of the elements of the tuple has an impossible (outside the range of the type) value, then the entire tuple too. + if (value.isNull() && !context.getSettings().transform_null_in) + break; + + tuple_values[i] = value; + } + + if (i == tuple_size) + for (i = 0; i < tuple_size; ++i) + columns[i]->insert(tuple_values[i]); + } + else + throw Exception("Incorrect element of set", ErrorCodes::INCORRECT_ELEMENT_OF_SET); + } + + return header.cloneWithColumns(std::move(columns)); +} + +/** Create a block for set from literal. + * 'set_element_types' - types of what are on the left hand side of IN. + * 'right_arg' - Literal - Tuple or Array. + */ +static Block createBlockForSet( + const DataTypePtr & left_arg_type, + const ASTPtr & right_arg, + const DataTypes & set_element_types, + const Context & context) +{ auto [right_arg_value, right_arg_type] = evaluateConstantExpression(right_arg, context); - std::function get_type_depth; - get_type_depth = [&get_type_depth](const DataTypePtr & type) -> size_t - { - if (const auto * array_type = typeid_cast(type.get())) - return 1 + get_type_depth(array_type->getNestedType()); - else if (const auto * tuple_type = typeid_cast(type.get())) - return 1 + (tuple_type->getElements().empty() ? 0 : get_type_depth(tuple_type->getElements().at(0))); - - return 0; - }; - - const size_t left_type_depth = get_type_depth(left_arg_type); - const size_t right_type_depth = get_type_depth(right_arg_type); + const size_t left_type_depth = getTypeDepth(left_arg_type); + const size_t right_type_depth = getTypeDepth(right_arg_type); auto throw_unsupported_type = [](const auto & type) { @@ -187,10 +269,105 @@ SetPtr makeExplicitSet( else throw_unsupported_type(right_arg_type); - SetPtr set = std::make_shared(size_limits, create_ordered_set, context.getSettingsRef().transform_null_in); + return block; +} - set->setHeader(block); +/** Create a block for set from expression. + * 'set_element_types' - types of what are on the left hand side of IN. + * 'right_arg' - list of values: 1, 2, 3 or list of tuples: (1, 2), (3, 4), (5, 6). + * + * We need special implementation for ASTFunction, because in case, when we interpret + * large tuple or array as function, `evaluateConstantExpression` works extremely slow. + */ +static Block createBlockForSet( + const DataTypePtr & left_arg_type, + const std::shared_ptr & right_arg, + const DataTypes & set_element_types, + const Context & context) +{ + auto get_tuple_type_from_ast = [&context](const auto & func) -> DataTypePtr + { + if (func && (func->name == "tuple" || func->name == "array") && !func->arguments->children.empty()) + { + /// Won't parse all values of outer tuple. + auto element = func->arguments->children.at(0); + std::pair value_raw = evaluateConstantExpression(element, context); + return std::make_shared(DataTypes({value_raw.second})); + } + + return evaluateConstantExpression(func, context).second; + }; + + const DataTypePtr & right_arg_type = get_tuple_type_from_ast(right_arg); + + size_t left_tuple_depth = getTypeDepth(left_arg_type); + size_t right_tuple_depth = getTypeDepth(right_arg_type); + ASTPtr elements_ast; + + /// 1 in 1; (1, 2) in (1, 2); identity(tuple(tuple(tuple(1)))) in tuple(tuple(tuple(1))); etc. + if (left_tuple_depth == right_tuple_depth) + { + ASTPtr exp_list = std::make_shared(); + exp_list->children.push_back(right_arg); + elements_ast = exp_list; + } + /// 1 in (1, 2); (1, 2) in ((1, 2), (3, 4)); etc. + else if (left_tuple_depth + 1 == right_tuple_depth) + { + const auto * set_func = right_arg->as(); + if (!set_func || (set_func->name != "tuple" && set_func->name != "array")) + throw Exception("Incorrect type of 2nd argument for function 'in'" + ". Must be subquery or set of elements with type " + left_arg_type->getName() + ".", + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + + elements_ast = set_func->arguments; + } + else + throw Exception("Invalid types for IN function: " + + left_arg_type->getName() + " and " + right_arg_type->getName() + ".", + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + + return createBlockFromAST(elements_ast, set_element_types, context); +} + +SetPtr makeExplicitSet( + const ASTFunction * node, const Block & sample_block, bool create_ordered_set, + const Context & context, const SizeLimits & size_limits, PreparedSets & prepared_sets) +{ + const IAST & args = *node->arguments; + + if (args.children.size() != 2) + throw Exception("Wrong number of arguments passed to function in", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + + const ASTPtr & left_arg = args.children.at(0); + const ASTPtr & right_arg = args.children.at(1); + + const DataTypePtr & left_arg_type = sample_block.getByName(left_arg->getColumnName()).type; + + DataTypes set_element_types = {left_arg_type}; + const auto * left_tuple_type = typeid_cast(left_arg_type.get()); + if (left_tuple_type && left_tuple_type->getElements().size() != 1) + set_element_types = left_tuple_type->getElements(); + + for (auto & element_type : set_element_types) + if (const auto * low_cardinality_type = typeid_cast(element_type.get())) + element_type = low_cardinality_type->getDictionaryType(); + + auto set_key = PreparedSetKey::forLiteral(*right_arg, set_element_types); + if (prepared_sets.count(set_key)) + return prepared_sets.at(set_key); /// Already prepared. + + Block block; + const auto & right_arg_func = std::dynamic_pointer_cast(right_arg); + if (right_arg_func && (right_arg_func->name == "tuple" || right_arg_func->name == "array")) + block = createBlockForSet(left_arg_type, right_arg_func, set_element_types, context); + else + block = createBlockForSet(left_arg_type, right_arg, set_element_types, context); + + SetPtr set = std::make_shared(size_limits, create_ordered_set, context.getSettingsRef().transform_null_in); + set->setHeader(block.cloneEmpty()); set->insertFromBlock(block); + set->finishInsert(); prepared_sets[set_key] = set; return set; diff --git a/src/Interpreters/Aggregator.cpp b/src/Interpreters/Aggregator.cpp index 13c7f6ddb35..2a2c66341dc 100644 --- a/src/Interpreters/Aggregator.cpp +++ b/src/Interpreters/Aggregator.cpp @@ -765,7 +765,8 @@ bool Aggregator::executeOnBlock(Columns columns, UInt64 num_rows, AggregatedData && worth_convert_to_two_level) { size_t size = current_memory_usage + params.min_free_disk_space; - const std::string tmp_path = params.tmp_volume->getNextDisk()->getPath(); + + std::string tmp_path = params.tmp_volume->getDisk()->getPath(); // enoughSpaceInDirectory() is not enough to make it right, since // another process (or another thread of aggregator) can consume all @@ -851,9 +852,12 @@ void Aggregator::writeToTemporaryFile(AggregatedDataVariants & data_variants, co ReadableSize(uncompressed_bytes / elapsed_seconds), ReadableSize(compressed_bytes / elapsed_seconds)); } + + void Aggregator::writeToTemporaryFile(AggregatedDataVariants & data_variants) { - return writeToTemporaryFile(data_variants, params.tmp_volume->getNextDisk()->getPath()); + String tmp_path = params.tmp_volume->getDisk()->getPath(); + return writeToTemporaryFile(data_variants, tmp_path); } diff --git a/src/Interpreters/Aggregator.h b/src/Interpreters/Aggregator.h index 87480301c69..5ddcb778482 100644 --- a/src/Interpreters/Aggregator.h +++ b/src/Interpreters/Aggregator.h @@ -24,6 +24,8 @@ #include #include +#include + #include #include @@ -45,9 +47,6 @@ namespace ErrorCodes class IBlockOutputStream; -class VolumeJBOD; -using VolumeJBODPtr = std::shared_ptr; - /** Different data structures that can be used for aggregation * For efficiency, the aggregation data itself is put into the pool. * Data and pool ownership (states of aggregate functions) @@ -878,7 +877,7 @@ public: /// Return empty result when aggregating without keys on empty set. bool empty_result_for_aggregation_by_empty_set; - VolumeJBODPtr tmp_volume; + VolumePtr tmp_volume; /// Settings is used to determine cache size. No threads are created. size_t max_threads; @@ -891,7 +890,7 @@ public: size_t group_by_two_level_threshold_, size_t group_by_two_level_threshold_bytes_, size_t max_bytes_before_external_group_by_, bool empty_result_for_aggregation_by_empty_set_, - VolumeJBODPtr tmp_volume_, size_t max_threads_, + VolumePtr tmp_volume_, size_t max_threads_, size_t min_free_disk_space_) : src_header(src_header_), keys(keys_), aggregates(aggregates_), keys_size(keys.size()), aggregates_size(aggregates.size()), diff --git a/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp b/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp index 51f7e93552a..5c41b4a1fc0 100644 --- a/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp +++ b/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp @@ -80,7 +80,7 @@ QueryPipeline createLocalStream( pipeline.addSimpleTransform([&](const Block & source_header) { return std::make_shared( - source_header, header, ConvertingTransform::MatchColumnsMode::Name); + source_header, header, ConvertingTransform::MatchColumnsMode::Name, true); }); /** Materialization is needed, since from remote servers the constants come materialized. diff --git a/src/Interpreters/Context.cpp b/src/Interpreters/Context.cpp index 98816a4eab9..a45bac35cd8 100644 --- a/src/Interpreters/Context.cpp +++ b/src/Interpreters/Context.cpp @@ -319,7 +319,7 @@ struct ContextShared ConfigurationPtr config; /// Global configuration settings. String tmp_path; /// Path to the temporary files that occur when processing the request. - mutable VolumeJBODPtr tmp_volume; /// Volume for the the temporary files that occur when processing the request. + mutable VolumePtr tmp_volume; /// Volume for the the temporary files that occur when processing the request. mutable std::optional embedded_dictionaries; /// Metrica's dictionaries. Have lazy initialization. mutable std::optional external_dictionaries_loader; @@ -547,7 +547,7 @@ String Context::getDictionariesLibPath() const return shared->dictionaries_lib_path; } -VolumeJBODPtr Context::getTemporaryVolume() const +VolumePtr Context::getTemporaryVolume() const { auto lock = getLock(); return shared->tmp_volume; @@ -572,7 +572,7 @@ void Context::setPath(const String & path) shared->dictionaries_lib_path = shared->path + "dictionaries_lib/"; } -VolumeJBODPtr Context::setTemporaryStorage(const String & path, const String & policy_name) +VolumePtr Context::setTemporaryStorage(const String & path, const String & policy_name) { std::lock_guard lock(shared->storage_policies_mutex); @@ -583,7 +583,7 @@ VolumeJBODPtr Context::setTemporaryStorage(const String & path, const String & p shared->tmp_path += '/'; auto disk = std::make_shared("_tmp_default", shared->tmp_path, 0); - shared->tmp_volume = std::make_shared("_tmp_default", std::vector{disk}, 0); + shared->tmp_volume = std::make_shared("_tmp_default", disk); } else { diff --git a/src/Interpreters/Context.h b/src/Interpreters/Context.h index 251e7f32311..23a4be82cb8 100644 --- a/src/Interpreters/Context.h +++ b/src/Interpreters/Context.h @@ -108,8 +108,8 @@ using StoragePolicySelectorPtr = std::shared_ptr; class IOutputFormat; using OutputFormatPtr = std::shared_ptr; -class VolumeJBOD; -using VolumeJBODPtr = std::shared_ptr; +class IVolume; +using VolumePtr = std::shared_ptr; struct NamedSession; @@ -227,14 +227,14 @@ public: String getUserFilesPath() const; String getDictionariesLibPath() const; - VolumeJBODPtr getTemporaryVolume() const; + VolumePtr getTemporaryVolume() const; void setPath(const String & path); void setFlagsPath(const String & path); void setUserFilesPath(const String & path); void setDictionariesLibPath(const String & path); - VolumeJBODPtr setTemporaryStorage(const String & path, const String & policy_name = ""); + VolumePtr setTemporaryStorage(const String & path, const String & policy_name = ""); using ConfigurationPtr = Poco::AutoPtr; diff --git a/src/Interpreters/InterpreterSelectQuery.cpp b/src/Interpreters/InterpreterSelectQuery.cpp index c13ed22b111..f5ea9ec965d 100644 --- a/src/Interpreters/InterpreterSelectQuery.cpp +++ b/src/Interpreters/InterpreterSelectQuery.cpp @@ -474,7 +474,7 @@ void InterpreterSelectQuery::buildQueryPlan(QueryPlan & query_plan) /// We must guarantee that result structure is the same as in getSampleBlock() if (!blocksHaveEqualStructure(query_plan.getCurrentDataStream().header, result_header)) { - auto converting = std::make_unique(query_plan.getCurrentDataStream(), result_header); + auto converting = std::make_unique(query_plan.getCurrentDataStream(), result_header, true); query_plan.addStep(std::move(converting)); } } diff --git a/src/Interpreters/Set.cpp b/src/Interpreters/Set.cpp index 07bd574a197..19f67bea42c 100644 --- a/src/Interpreters/Set.cpp +++ b/src/Interpreters/Set.cpp @@ -39,7 +39,6 @@ namespace ErrorCodes extern const int LOGICAL_ERROR; extern const int SET_SIZE_LIMIT_EXCEEDED; extern const int TYPE_MISMATCH; - extern const int INCORRECT_ELEMENT_OF_SET; extern const int NUMBER_OF_COLUMNS_DOESNT_MATCH; } @@ -216,97 +215,6 @@ bool Set::insertFromBlock(const Block & block) } -static Field extractValueFromNode(const ASTPtr & node, const IDataType & type, const Context & context) -{ - if (const auto * lit = node->as()) - { - return convertFieldToType(lit->value, type); - } - else if (node->as()) - { - std::pair value_raw = evaluateConstantExpression(node, context); - return convertFieldToType(value_raw.first, type, value_raw.second.get()); - } - else - throw Exception("Incorrect element of set. Must be literal or constant expression.", ErrorCodes::INCORRECT_ELEMENT_OF_SET); -} - -void Set::createFromAST(const DataTypes & types, ASTPtr node, const Context & context) -{ - /// Will form a block with values from the set. - - Block header; - size_t num_columns = types.size(); - for (size_t i = 0; i < num_columns; ++i) - header.insert(ColumnWithTypeAndName(types[i]->createColumn(), types[i], "_" + toString(i))); - setHeader(header); - - MutableColumns columns = header.cloneEmptyColumns(); - - DataTypePtr tuple_type; - Row tuple_values; - const auto & list = node->as(); - for (const auto & elem : list.children) - { - if (num_columns == 1) - { - Field value = extractValueFromNode(elem, *types[0], context); - - if (!value.isNull() || context.getSettingsRef().transform_null_in) - columns[0]->insert(value); - } - else if (const auto * func = elem->as()) - { - Field function_result; - const Tuple * tuple = nullptr; - if (func->name != "tuple") - { - if (!tuple_type) - tuple_type = std::make_shared(types); - - function_result = extractValueFromNode(elem, *tuple_type, context); - if (function_result.getType() != Field::Types::Tuple) - throw Exception("Invalid type of set. Expected tuple, got " + String(function_result.getTypeName()), - ErrorCodes::INCORRECT_ELEMENT_OF_SET); - - tuple = &function_result.get(); - } - - size_t tuple_size = tuple ? tuple->size() : func->arguments->children.size(); - if (tuple_size != num_columns) - throw Exception("Incorrect size of tuple in set: " + toString(tuple_size) + " instead of " + toString(num_columns), - ErrorCodes::INCORRECT_ELEMENT_OF_SET); - - if (tuple_values.empty()) - tuple_values.resize(tuple_size); - - size_t i = 0; - for (; i < tuple_size; ++i) - { - Field value = tuple ? (*tuple)[i] - : extractValueFromNode(func->arguments->children[i], *types[i], context); - - /// If at least one of the elements of the tuple has an impossible (outside the range of the type) value, then the entire tuple too. - if (value.isNull() && !context.getSettings().transform_null_in) - break; - - tuple_values[i] = value; - } - - if (i == tuple_size) - for (i = 0; i < tuple_size; ++i) - columns[i]->insert(tuple_values[i]); - } - else - throw Exception("Incorrect element of set", ErrorCodes::INCORRECT_ELEMENT_OF_SET); - } - - Block block = header.cloneWithColumns(std::move(columns)); - insertFromBlock(block); - finishInsert(); -} - - ColumnPtr Set::execute(const Block & block, bool negative) const { size_t num_key_columns = block.columns(); diff --git a/src/Interpreters/Set.h b/src/Interpreters/Set.h index 4df89831896..faae9c7318e 100644 --- a/src/Interpreters/Set.h +++ b/src/Interpreters/Set.h @@ -41,12 +41,6 @@ public: /** Set can be created either from AST or from a stream of data (subquery result). */ - /** Create a Set from expression (specified literally in the query). - * 'types' - types of what are on the left hand side of IN. - * 'node' - list of values: 1, 2, 3 or list of tuples: (1, 2), (3, 4), (5, 6). - */ - void createFromAST(const DataTypes & types, ASTPtr node, const Context & context); - /** Create a Set from stream. * Call setHeader, then call insertFromBlock for each block. */ diff --git a/src/Interpreters/SortedBlocksWriter.cpp b/src/Interpreters/SortedBlocksWriter.cpp index 3fa6fbe153e..0dba09bc80f 100644 --- a/src/Interpreters/SortedBlocksWriter.cpp +++ b/src/Interpreters/SortedBlocksWriter.cpp @@ -203,7 +203,7 @@ BlockInputStreamPtr SortedBlocksWriter::streamFromFile(const TmpFilePtr & file) String SortedBlocksWriter::getPath() const { - return volume->getNextDisk()->getPath(); + return volume->getDisk()->getPath(); } diff --git a/src/Interpreters/SortedBlocksWriter.h b/src/Interpreters/SortedBlocksWriter.h index 11e7c8c1413..3c7bd8dc625 100644 --- a/src/Interpreters/SortedBlocksWriter.h +++ b/src/Interpreters/SortedBlocksWriter.h @@ -16,8 +16,8 @@ class TableJoin; class MergeJoinCursor; struct MergeJoinEqualRange; -class VolumeJBOD; -using VolumeJBODPtr = std::shared_ptr; +class IVolume; +using VolumePtr = std::shared_ptr; struct SortedBlocksWriter { @@ -63,7 +63,7 @@ struct SortedBlocksWriter std::mutex insert_mutex; std::condition_variable flush_condvar; const SizeLimits & size_limits; - VolumeJBODPtr volume; + VolumePtr volume; Block sample_block; const SortDescription & sort_description; Blocks inserted_blocks; @@ -76,7 +76,7 @@ struct SortedBlocksWriter size_t flush_number = 0; size_t flush_inflight = 0; - SortedBlocksWriter(const SizeLimits & size_limits_, VolumeJBODPtr volume_, const Block & sample_block_, + SortedBlocksWriter(const SizeLimits & size_limits_, VolumePtr volume_, const Block & sample_block_, const SortDescription & description, size_t rows_in_block_, size_t num_files_to_merge_, const String & codec_) : size_limits(size_limits_) , volume(volume_) diff --git a/src/Interpreters/TableJoin.cpp b/src/Interpreters/TableJoin.cpp index 282e253f002..01b75b95d19 100644 --- a/src/Interpreters/TableJoin.cpp +++ b/src/Interpreters/TableJoin.cpp @@ -14,7 +14,7 @@ namespace DB { -TableJoin::TableJoin(const Settings & settings, VolumeJBODPtr tmp_volume_) +TableJoin::TableJoin(const Settings & settings, VolumePtr tmp_volume_) : size_limits(SizeLimits{settings.max_rows_in_join, settings.max_bytes_in_join, settings.join_overflow_mode}) , default_max_bytes(settings.default_max_bytes_in_join) , join_use_nulls(settings.join_use_nulls) diff --git a/src/Interpreters/TableJoin.h b/src/Interpreters/TableJoin.h index 6fb7e72d40c..77e32c1076d 100644 --- a/src/Interpreters/TableJoin.h +++ b/src/Interpreters/TableJoin.h @@ -24,8 +24,8 @@ class DictionaryReader; struct Settings; -class VolumeJBOD; -using VolumeJBODPtr = std::shared_ptr; +class IVolume; +using VolumePtr = std::shared_ptr; class TableJoin { @@ -71,11 +71,11 @@ class TableJoin /// Original name -> name. Only ranamed columns. std::unordered_map renames; - VolumeJBODPtr tmp_volume; + VolumePtr tmp_volume; public: TableJoin() = default; - TableJoin(const Settings &, VolumeJBODPtr tmp_volume); + TableJoin(const Settings &, VolumePtr tmp_volume); /// for StorageJoin TableJoin(SizeLimits limits, bool use_nulls, ASTTableJoin::Kind kind, ASTTableJoin::Strictness strictness, @@ -97,7 +97,7 @@ public: ASTTableJoin::Strictness strictness() const { return table_join.strictness; } bool sameStrictnessAndKind(ASTTableJoin::Strictness, ASTTableJoin::Kind) const; const SizeLimits & sizeLimits() const { return size_limits; } - VolumeJBODPtr getTemporaryVolume() { return tmp_volume; } + VolumePtr getTemporaryVolume() { return tmp_volume; } bool allowMergeJoin() const; bool allowDictJoin(const String & dict_key, const Block & sample_block, Names &, NamesAndTypesList &) const; bool preferMergeJoin() const { return join_algorithm == JoinAlgorithm::PREFER_PARTIAL_MERGE; } diff --git a/src/Parsers/ASTDictionary.h b/src/Parsers/ASTDictionary.h index 5d7ed95d41d..b6b089cc70e 100644 --- a/src/Parsers/ASTDictionary.h +++ b/src/Parsers/ASTDictionary.h @@ -82,19 +82,19 @@ class ASTDictionary : public IAST { public: /// Dictionary keys -- one or more - ASTExpressionList * primary_key; + ASTExpressionList * primary_key = nullptr; /// Dictionary external source, doesn't have own AST, because /// source parameters absolutely different for different sources - ASTFunctionWithKeyValueArguments * source; + ASTFunctionWithKeyValueArguments * source = nullptr; /// Lifetime of dictionary (required part) - ASTDictionaryLifetime * lifetime; + ASTDictionaryLifetime * lifetime = nullptr; /// Layout of dictionary (required part) - ASTDictionaryLayout * layout; + ASTDictionaryLayout * layout = nullptr; /// Range for dictionary (only for range-hashed dictionaries) - ASTDictionaryRange * range; + ASTDictionaryRange * range = nullptr; /// Settings for dictionary (optionally) - ASTDictionarySettings * dict_settings; + ASTDictionarySettings * dict_settings = nullptr; String getID(char) const override { return "Dictionary definition"; } diff --git a/src/Parsers/tests/gtest_dictionary_parser.cpp b/src/Parsers/tests/gtest_dictionary_parser.cpp index 31b6d6cdd81..b5a0f16d5d2 100644 --- a/src/Parsers/tests/gtest_dictionary_parser.cpp +++ b/src/Parsers/tests/gtest_dictionary_parser.cpp @@ -1,9 +1,6 @@ -#include - #include #include #include -#include #include #include #include @@ -11,7 +8,6 @@ #include #include #include -#include #include diff --git a/src/Parsers/tests/lexer.cpp b/src/Parsers/tests/lexer.cpp index 074338d15b9..b1d0bb6212c 100644 --- a/src/Parsers/tests/lexer.cpp +++ b/src/Parsers/tests/lexer.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/src/Parsers/tests/lexer_fuzzer.cpp b/src/Parsers/tests/lexer_fuzzer.cpp index 83d7396b291..8ebe39cb67b 100644 --- a/src/Parsers/tests/lexer_fuzzer.cpp +++ b/src/Parsers/tests/lexer_fuzzer.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/src/Processors/Executors/PipelineExecutor.cpp b/src/Processors/Executors/PipelineExecutor.cpp index e61443dcfad..aff93883568 100644 --- a/src/Processors/Executors/PipelineExecutor.cpp +++ b/src/Processors/Executors/PipelineExecutor.cpp @@ -526,9 +526,16 @@ void PipelineExecutor::finalizeExecution() return; bool all_processors_finished = true; + for (auto & node : graph) - if (node.status != ExecStatus::Finished) /// Single thread, do not hold mutex + { + if (node.status != ExecStatus::Finished) + { + /// Single thread, do not hold mutex all_processors_finished = false; + break; + } + } if (!all_processors_finished) throw Exception("Pipeline stuck. Current state:\n" + dumpPipeline(), ErrorCodes::LOGICAL_ERROR); diff --git a/src/Processors/QueryPlan/ConvertingStep.cpp b/src/Processors/QueryPlan/ConvertingStep.cpp index 4713a3c4402..356aad63824 100644 --- a/src/Processors/QueryPlan/ConvertingStep.cpp +++ b/src/Processors/QueryPlan/ConvertingStep.cpp @@ -16,9 +16,10 @@ static ITransformingStep::DataStreamTraits getTraits() }; } -ConvertingStep::ConvertingStep(const DataStream & input_stream_, Block result_header_) +ConvertingStep::ConvertingStep(const DataStream & input_stream_, Block result_header_, bool ignore_constant_values_) : ITransformingStep(input_stream_, result_header_, getTraits()) , result_header(std::move(result_header_)) + , ignore_constant_values(ignore_constant_values_) { updateDistinctColumns(output_stream->header, output_stream->distinct_columns); } @@ -27,14 +28,14 @@ void ConvertingStep::transformPipeline(QueryPipeline & pipeline) { pipeline.addSimpleTransform([&](const Block & header) { - return std::make_shared(header, result_header, ConvertingTransform::MatchColumnsMode::Name); + return std::make_shared(header, result_header, ConvertingTransform::MatchColumnsMode::Name, ignore_constant_values); }); } void ConvertingStep::describeActions(FormatSettings & settings) const { const auto & header = input_streams[0].header; - auto conversion = ConvertingTransform(header, result_header, ConvertingTransform::MatchColumnsMode::Name) + auto conversion = ConvertingTransform(header, result_header, ConvertingTransform::MatchColumnsMode::Name, ignore_constant_values) .getConversion(); auto dump_description = [&](const ColumnWithTypeAndName & elem, bool is_const) diff --git a/src/Processors/QueryPlan/ConvertingStep.h b/src/Processors/QueryPlan/ConvertingStep.h index 5591b49028c..70fd34330d1 100644 --- a/src/Processors/QueryPlan/ConvertingStep.h +++ b/src/Processors/QueryPlan/ConvertingStep.h @@ -8,7 +8,7 @@ namespace DB class ConvertingStep : public ITransformingStep { public: - ConvertingStep(const DataStream & input_stream_, Block result_header_); + ConvertingStep(const DataStream & input_stream_, Block result_header_, bool ignore_constant_values_ = false); String getName() const override { return "Converting"; } @@ -18,6 +18,8 @@ public: private: Block result_header; + /// Do not check that constants are same. Use value from result_header. + bool ignore_constant_values; }; } diff --git a/src/Processors/Sources/SourceWithProgress.cpp b/src/Processors/Sources/SourceWithProgress.cpp index 6488289d5ce..d6972f99369 100644 --- a/src/Processors/Sources/SourceWithProgress.cpp +++ b/src/Processors/Sources/SourceWithProgress.cpp @@ -3,6 +3,12 @@ #include #include +namespace ProfileEvents +{ + extern const Event SelectedRows; + extern const Event SelectedBytes; +} + namespace DB { @@ -107,6 +113,9 @@ void SourceWithProgress::progress(const Progress & value) if (quota && limits.mode == LimitsMode::LIMITS_TOTAL) quota->used({Quota::READ_ROWS, value.read_rows}, {Quota::READ_BYTES, value.read_bytes}); } + + ProfileEvents::increment(ProfileEvents::SelectedRows, value.read_rows); + ProfileEvents::increment(ProfileEvents::SelectedBytes, value.read_bytes); } } diff --git a/src/Processors/Transforms/ConvertingTransform.cpp b/src/Processors/Transforms/ConvertingTransform.cpp index 95830f2a1c3..2d927e0fbde 100644 --- a/src/Processors/Transforms/ConvertingTransform.cpp +++ b/src/Processors/Transforms/ConvertingTransform.cpp @@ -35,9 +35,11 @@ static ColumnPtr castColumnWithDiagnostic( ConvertingTransform::ConvertingTransform( Block source_header_, Block result_header_, - MatchColumnsMode mode_) + MatchColumnsMode mode_, + bool ignore_constant_values_) : ISimpleTransform(std::move(source_header_), std::move(result_header_), false) , conversion(getOutputPort().getHeader().columns()) + , ignore_constant_values(ignore_constant_values_) { const auto & source = getInputPort().getHeader(); const auto & result = getOutputPort().getHeader(); @@ -79,7 +81,7 @@ ConvertingTransform::ConvertingTransform( { if (const auto * src_const = typeid_cast(src_elem.column.get())) { - if (res_const->getField() != src_const->getField()) + if (!ignore_constant_values && res_const->getField() != src_const->getField()) throw Exception("Cannot convert column " + backQuoteIfNeed(res_elem.name) + " because " "it is constant but values of constants are different in source and result", ErrorCodes::ILLEGAL_COLUMN); @@ -115,6 +117,12 @@ void ConvertingTransform::transform(Chunk & chunk) src_elem.column = src_columns[conversion[res_pos]]; auto res_elem = result.getByPosition(res_pos); + if (ignore_constant_values && isColumnConst(*res_elem.column)) + { + res_columns.emplace_back(res_elem.column->cloneResized(num_rows)); + continue; + } + ColumnPtr converted = castColumnWithDiagnostic(src_elem, res_elem); if (!isColumnConst(*res_elem.column)) diff --git a/src/Processors/Transforms/ConvertingTransform.h b/src/Processors/Transforms/ConvertingTransform.h index b4b42dcb6ea..68a914e8441 100644 --- a/src/Processors/Transforms/ConvertingTransform.h +++ b/src/Processors/Transforms/ConvertingTransform.h @@ -31,7 +31,8 @@ public: ConvertingTransform( Block source_header_, Block result_header_, - MatchColumnsMode mode_); + MatchColumnsMode mode_, + bool ignore_constant_values_ = false); /// Do not check that constants are same. Use value from result_header. String getName() const override { return "Converting"; } @@ -43,6 +44,11 @@ protected: private: /// How to construct result block. Position in source block, where to get each column. ColumnNumbers conversion; + /// Do not check that constants are same. Use value from result_header. + /// This is needed in case run functions which are constatn in query scope, + /// but may return different result being executed remotely, like `now64()` or `randConstant()`. + /// In this case we replace constants from remote source to constatns from initiator. + bool ignore_constant_values; }; } diff --git a/src/Processors/tests/processors_test_aggregation.cpp b/src/Processors/tests/processors_test_aggregation.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/Processors/tests/processors_test_merge_sorting_transform.cpp b/src/Processors/tests/processors_test_merge_sorting_transform.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index cd26f9e88fc..95f56b715b8 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -366,7 +366,7 @@ void HTTPHandler::processQuery( if (buffer_until_eof) { - const std::string tmp_path(context.getTemporaryVolume()->getNextDisk()->getPath()); + const std::string tmp_path(context.getTemporaryVolume()->getDisk()->getPath()); const std::string tmp_path_template(tmp_path + "http_buffers/"); auto create_tmp_disk_buffer = [tmp_path_template] (const WriteBufferPtr &) @@ -475,16 +475,21 @@ void HTTPHandler::processQuery( reserved_param_suffixes.emplace_back("_structure"); } + std::string database = request.get("X-ClickHouse-Database", ""); + std::string default_format = request.get("X-ClickHouse-Format", ""); + SettingsChanges settings_changes; for (const auto & [key, value] : params) { if (key == "database") { - context.setCurrentDatabase(value); + if (database.empty()) + database = value; } else if (key == "default_format") { - context.setDefaultFormat(value); + if (default_format.empty()) + default_format = value; } else if (param_could_be_skipped(key)) { @@ -497,6 +502,12 @@ void HTTPHandler::processQuery( } } + if (!database.empty()) + context.setCurrentDatabase(database); + + if (!default_format.empty()) + context.setDefaultFormat(default_format); + /// For external data we also want settings context.checkSettingsConstraints(settings_changes); context.applySettingsChanges(settings_changes); diff --git a/src/Storages/Distributed/DistributedBlockOutputStream.cpp b/src/Storages/Distributed/DistributedBlockOutputStream.cpp index 546eb5a15a4..5afd000f279 100644 --- a/src/Storages/Distributed/DistributedBlockOutputStream.cpp +++ b/src/Storages/Distributed/DistributedBlockOutputStream.cpp @@ -561,7 +561,9 @@ void DistributedBlockOutputStream::writeToShard(const Block & block, const std:: /// and keep monitor thread out from reading incomplete data std::string first_file_tmp_path{}; - const auto & [disk, data_path] = storage.getPath(); + auto reservation = storage.getStoragePolicy()->reserve(block.bytes()); + auto disk = reservation->getDisk()->getPath(); + auto data_path = storage.getRelativeDataPath(); auto it = dir_names.begin(); /// on first iteration write block to a temporary directory for subsequent diff --git a/src/Storages/MergeTree/MergeTreeMutationStatus.cpp b/src/Storages/MergeTree/MergeTreeMutationStatus.cpp index 4819cf9b2a9..54098a65cd0 100644 --- a/src/Storages/MergeTree/MergeTreeMutationStatus.cpp +++ b/src/Storages/MergeTree/MergeTreeMutationStatus.cpp @@ -9,14 +9,17 @@ namespace DB namespace ErrorCodes { extern const int UNFINISHED; + extern const int LOGICAL_ERROR; } -void checkMutationStatus(std::optional & status, const Strings & mutation_ids) +void checkMutationStatus(std::optional & status, const std::set & mutation_ids) { + if (mutation_ids.empty()) + throw Exception(ErrorCodes::LOGICAL_ERROR, "Cannot check mutation status because no mutation ids provided"); + if (!status) { - assert(mutation_ids.size() == 1); - throw Exception(ErrorCodes::UNFINISHED, "Mutation {} was killed", mutation_ids[0]); + throw Exception(ErrorCodes::UNFINISHED, "Mutation {} was killed", *mutation_ids.begin()); } else if (!status->is_done && !status->latest_fail_reason.empty()) { diff --git a/src/Storages/MergeTree/MergeTreeMutationStatus.h b/src/Storages/MergeTree/MergeTreeMutationStatus.h index 62d7c1bbbcd..d3a66bd09d6 100644 --- a/src/Storages/MergeTree/MergeTreeMutationStatus.h +++ b/src/Storages/MergeTree/MergeTreeMutationStatus.h @@ -33,6 +33,6 @@ struct MergeTreeMutationStatus /// (latest_fail_reason not empty) or if mutation was killed (status empty /// optional). mutation_ids passed separately, because status may be empty and /// we can execute multiple mutations at once -void checkMutationStatus(std::optional & status, const Strings & mutation_ids); +void checkMutationStatus(std::optional & status, const std::set & mutation_ids); } diff --git a/src/Storages/MergeTree/ReplicatedMergeTreeQueue.cpp b/src/Storages/MergeTree/ReplicatedMergeTreeQueue.cpp index 4ff63f9c2de..a3ed86cb2b6 100644 --- a/src/Storages/MergeTree/ReplicatedMergeTreeQueue.cpp +++ b/src/Storages/MergeTree/ReplicatedMergeTreeQueue.cpp @@ -1538,7 +1538,7 @@ void ReplicatedMergeTreeQueue::getInsertTimes(time_t & out_min_unprocessed_inser } -std::optional ReplicatedMergeTreeQueue::getIncompleteMutationsStatus(const String & znode_name, Strings * mutation_ids) const +std::optional ReplicatedMergeTreeQueue::getIncompleteMutationsStatus(const String & znode_name, std::set * mutation_ids) const { std::lock_guard lock(state_mutex); @@ -1568,7 +1568,7 @@ std::optional ReplicatedMergeTreeQueue::getIncompleteMu { /// All mutations with the same failure if (!it->second->is_done && it->second->latest_fail_reason == status.latest_fail_reason) - mutation_ids->push_back(it->second->entry->znode_name); + mutation_ids->insert(it->second->entry->znode_name); } } } diff --git a/src/Storages/MergeTree/ReplicatedMergeTreeQueue.h b/src/Storages/MergeTree/ReplicatedMergeTreeQueue.h index c330631d9dd..d68833bb380 100644 --- a/src/Storages/MergeTree/ReplicatedMergeTreeQueue.h +++ b/src/Storages/MergeTree/ReplicatedMergeTreeQueue.h @@ -402,9 +402,11 @@ public: /// Return empty optional if mutation was killed. Otherwise return partially /// filled mutation status with information about error (latest_fail*) and - /// is_done. mutation_ids filled with all mutations with same errors, because - /// they may be executed simultaneously as one mutation. - std::optional getIncompleteMutationsStatus(const String & znode_name, Strings * mutation_ids = nullptr) const; + /// is_done. mutation_ids filled with all mutations with same errors, + /// because they may be executed simultaneously as one mutation. Order is + /// important for better readability of exception message. If mutation was + /// killed doesn't return any ids. + std::optional getIncompleteMutationsStatus(const String & znode_name, std::set * mutation_ids = nullptr) const; std::vector getMutationsStatus() const; diff --git a/src/Storages/StorageDistributed.cpp b/src/Storages/StorageDistributed.cpp index d340a834973..8187b40588e 100644 --- a/src/Storages/StorageDistributed.cpp +++ b/src/Storages/StorageDistributed.cpp @@ -290,7 +290,7 @@ StorageDistributed::StorageDistributed( const String & cluster_name_, const Context & context_, const ASTPtr & sharding_key_, - const String & storage_policy_, + const String & storage_policy_name_, const String & relative_data_path_, bool attach_) : IStorage(id_) @@ -300,7 +300,6 @@ StorageDistributed::StorageDistributed( , log(&Poco::Logger::get("StorageDistributed (" + id_.table_name + ")")) , cluster_name(global_context->getMacros()->expand(cluster_name_)) , has_sharding_key(sharding_key_) - , storage_policy(storage_policy_) , relative_data_path(relative_data_path_) { StorageInMemoryMetadata storage_metadata; @@ -316,7 +315,11 @@ StorageDistributed::StorageDistributed( } if (!relative_data_path.empty()) - createStorage(); + { + storage_policy = global_context->getStoragePolicy(storage_policy_name_); + if (storage_policy->getVolumes().size() != 1) + throw Exception("Storage policy for Distributed table, should have exactly one volume", ErrorCodes::BAD_ARGUMENTS); + } /// Sanity check. Skip check if the table is already created to allow the server to start. if (!attach_ && !cluster_name.empty()) @@ -336,34 +339,14 @@ StorageDistributed::StorageDistributed( const String & cluster_name_, const Context & context_, const ASTPtr & sharding_key_, - const String & storage_policy_, + const String & storage_policy_name_, const String & relative_data_path_, bool attach) - : StorageDistributed(id_, columns_, constraints_, String{}, String{}, cluster_name_, context_, sharding_key_, storage_policy_, relative_data_path_, attach) + : StorageDistributed(id_, columns_, constraints_, String{}, String{}, cluster_name_, context_, sharding_key_, storage_policy_name_, relative_data_path_, attach) { remote_table_function_ptr = std::move(remote_table_function_ptr_); } -void StorageDistributed::createStorage() -{ - /// Create default policy with the relative_data_path_ - if (storage_policy.empty()) - { - std::string path(global_context->getPath()); - /// Disk must ends with '/' - if (!path.ends_with('/')) - path += '/'; - auto disk = std::make_shared("default", path, 0); - volume = std::make_shared("default", std::vector{disk}, 0); - } - else - { - auto policy = global_context->getStoragePolicy(storage_policy); - if (policy->getVolumes().size() != 1) - throw Exception("Policy for Distributed table, should have exactly one volume", ErrorCodes::BAD_ARGUMENTS); - volume = policy->getVolume(0); - } -} StoragePtr StorageDistributed::createWithOwnCluster( const StorageID & table_id_, @@ -539,7 +522,7 @@ BlockOutputStreamPtr StorageDistributed::write(const ASTPtr &, const StorageMeta const auto & settings = context.getSettingsRef(); /// Ban an attempt to make async insert into the table belonging to DatabaseMemory - if (!volume && !owned_cluster && !settings.insert_distributed_sync) + if (!storage_policy && !owned_cluster && !settings.insert_distributed_sync) { throw Exception("Storage " + getName() + " must has own data directory to enable asynchronous inserts", ErrorCodes::BAD_ARGUMENTS); @@ -595,10 +578,10 @@ void StorageDistributed::startup() if (remote_database.empty() && !remote_table_function_ptr) LOG_WARNING(log, "Name of remote database is empty. Default database will be used implicitly."); - if (!volume) + if (!storage_policy) return; - for (const DiskPtr & disk : volume->getDisks()) + for (const DiskPtr & disk : storage_policy->getDisks()) createDirectoryMonitors(disk->getPath()); for (const String & path : getDataPaths()) @@ -632,7 +615,7 @@ void StorageDistributed::drop() LOG_DEBUG(log, "Removing pending blocks for async INSERT from filesystem on DROP TABLE"); - auto disks = volume->getDisks(); + auto disks = storage_policy->getDisks(); for (const auto & disk : disks) disk->removeRecursive(relative_data_path); @@ -646,7 +629,7 @@ Strings StorageDistributed::getDataPaths() const if (relative_data_path.empty()) return paths; - for (const DiskPtr & disk : volume->getDisks()) + for (const DiskPtr & disk : storage_policy->getDisks()) paths.push_back(disk->getPath() + relative_data_path); return paths; @@ -669,9 +652,7 @@ void StorageDistributed::truncate(const ASTPtr &, const StorageMetadataPtr &, co StoragePolicyPtr StorageDistributed::getStoragePolicy() const { - if (storage_policy.empty()) - return {}; - return global_context->getStoragePolicy(storage_policy); + return storage_policy; } void StorageDistributed::createDirectoryMonitors(const std::string & disk) @@ -718,11 +699,6 @@ size_t StorageDistributed::getShardCount() const return getCluster()->getShardCount(); } -std::pair StorageDistributed::getPath() -{ - return {volume->getNextDisk()->getPath(), relative_data_path}; -} - ClusterPtr StorageDistributed::getCluster() const { return owned_cluster ? owned_cluster : global_context->getCluster(cluster_name); @@ -868,9 +844,11 @@ void StorageDistributed::rename(const String & new_path_to_table_data, const Sto renameOnDisk(new_path_to_table_data); renameInMemory(new_table_id); } + + void StorageDistributed::renameOnDisk(const String & new_path_to_table_data) { - for (const DiskPtr & disk : volume->getDisks()) + for (const DiskPtr & disk : storage_policy->getDisks()) { const String path(disk->getPath()); auto new_path = path + new_path_to_table_data; @@ -925,7 +903,7 @@ void registerStorageDistributed(StorageFactory & factory) String remote_table = engine_args[2]->as().value.safeGet(); const auto & sharding_key = engine_args.size() >= 4 ? engine_args[3] : nullptr; - const auto & storage_policy = engine_args.size() >= 5 ? engine_args[4]->as().value.safeGet() : ""; + const auto & storage_policy = engine_args.size() >= 5 ? engine_args[4]->as().value.safeGet() : "default"; /// Check that sharding_key exists in the table and has numeric type. if (sharding_key) diff --git a/src/Storages/StorageDistributed.h b/src/Storages/StorageDistributed.h index c2277b23f11..4caf063ce81 100644 --- a/src/Storages/StorageDistributed.h +++ b/src/Storages/StorageDistributed.h @@ -18,8 +18,8 @@ namespace DB struct Settings; class Context; -class VolumeJBOD; -using VolumeJBODPtr = std::shared_ptr; +class IVolume; +using VolumePtr = std::shared_ptr; class ExpressionActions; using ExpressionActionsPtr = std::shared_ptr; @@ -102,7 +102,7 @@ public: const ExpressionActionsPtr & getShardingKeyExpr() const { return sharding_key_expr; } const String & getShardingKeyColumnName() const { return sharding_key_column_name; } size_t getShardCount() const; - std::pair getPath(); + const String & getRelativeDataPath() const { return relative_data_path; } std::string getRemoteDatabaseName() const { return remote_database; } std::string getRemoteTableName() const { return remote_table; } std::string getClusterName() const { return cluster_name; } /// Returns empty string if tables is used by TableFunctionRemote @@ -163,7 +163,7 @@ protected: const String & cluster_name_, const Context & context_, const ASTPtr & sharding_key_, - const String & storage_policy_, + const String & storage_policy_name_, const String & relative_data_path_, bool attach_); @@ -175,16 +175,14 @@ protected: const String & cluster_name_, const Context & context_, const ASTPtr & sharding_key_, - const String & storage_policy_, + const String & storage_policy_name_, const String & relative_data_path_, bool attach); - void createStorage(); - - String storage_policy; String relative_data_path; + /// Can be empty if relative_data_path is empty. In this case, a directory for the data to be sent is not created. - VolumeJBODPtr volume; + StoragePolicyPtr storage_policy; struct ClusterNodeData { diff --git a/src/Storages/StorageMergeTree.cpp b/src/Storages/StorageMergeTree.cpp index 9ef89d62919..7335aef794b 100644 --- a/src/Storages/StorageMergeTree.cpp +++ b/src/Storages/StorageMergeTree.cpp @@ -417,7 +417,10 @@ void StorageMergeTree::waitForMutation(Int64 version, const String & file_name) mutation_wait_event.wait(lock, check); } - Strings mutation_ids; + /// At least we have our current mutation + std::set mutation_ids; + mutation_ids.insert(file_name); + auto mutation_status = getIncompleteMutationsStatus(version, &mutation_ids); checkMutationStatus(mutation_status, mutation_ids); @@ -449,7 +452,7 @@ bool comparator(const PartVersionWithName & f, const PartVersionWithName & s) } -std::optional StorageMergeTree::getIncompleteMutationsStatus(Int64 mutation_version, Strings * mutation_ids) const +std::optional StorageMergeTree::getIncompleteMutationsStatus(Int64 mutation_version, std::set * mutation_ids) const { std::lock_guard lock(currently_processing_in_background_mutex); @@ -467,7 +470,6 @@ std::optional StorageMergeTree::getIncompleteMutationsS { if (data_part->info.getDataVersion() < mutation_version) { - if (!mutation_entry.latest_fail_reason.empty()) { result.latest_failed_part = mutation_entry.latest_failed_part; @@ -483,7 +485,7 @@ std::optional StorageMergeTree::getIncompleteMutationsS for (auto it = mutations_begin_it; it != current_mutations_by_version.end(); ++it) /// All mutations with the same failure if (it->second.latest_fail_reason == result.latest_fail_reason) - mutation_ids->push_back(it->second.file_name); + mutation_ids->insert(it->second.file_name); } } diff --git a/src/Storages/StorageMergeTree.h b/src/Storages/StorageMergeTree.h index e12e646f04e..92679edd143 100644 --- a/src/Storages/StorageMergeTree.h +++ b/src/Storages/StorageMergeTree.h @@ -161,9 +161,11 @@ private: /// Return empty optional if mutation was killed. Otherwise return partially /// filled mutation status with information about error (latest_fail*) and - /// is_done. mutation_ids filled with mutations with the same errors, because we - /// can execute several mutations at once - std::optional getIncompleteMutationsStatus(Int64 mutation_version, Strings * mutation_ids = nullptr) const; + /// is_done. mutation_ids filled with mutations with the same errors, + /// because we can execute several mutations at once. Order is important for + /// better readability of exception message. If mutation was killed doesn't + /// return any ids. + std::optional getIncompleteMutationsStatus(Int64 mutation_version, std::set * mutation_ids = nullptr) const; void startBackgroundMovesIfNeeded() override; diff --git a/src/Storages/StorageReplicatedMergeTree.cpp b/src/Storages/StorageReplicatedMergeTree.cpp index e2a76f45b82..bf9b5ea6849 100644 --- a/src/Storages/StorageReplicatedMergeTree.cpp +++ b/src/Storages/StorageReplicatedMergeTree.cpp @@ -398,7 +398,10 @@ void StorageReplicatedMergeTree::waitMutationToFinishOnReplicas( throw Exception(ErrorCodes::UNFINISHED, "Mutation {} was killed, manually removed or table was dropped", mutation_id); } - Strings mutation_ids; + /// At least we have our current mutation + std::set mutation_ids; + mutation_ids.insert(mutation_id); + auto mutation_status = queue.getIncompleteMutationsStatus(mutation_id, &mutation_ids); checkMutationStatus(mutation_status, mutation_ids); diff --git a/src/Storages/System/StorageSystemStoragePolicies.cpp b/src/Storages/System/StorageSystemStoragePolicies.cpp index ec771ec2421..76a665d871c 100644 --- a/src/Storages/System/StorageSystemStoragePolicies.cpp +++ b/src/Storages/System/StorageSystemStoragePolicies.cpp @@ -1,7 +1,10 @@ -#include -#include #include + +#include +#include +#include #include +#include #include #include @@ -24,9 +27,11 @@ StorageSystemStoragePolicies::StorageSystemStoragePolicies(const std::string & n {"volume_name", std::make_shared()}, {"volume_priority", std::make_shared()}, {"disks", std::make_shared(std::make_shared())}, + {"volume_type", std::make_shared()}, {"max_data_part_size", std::make_shared()}, - {"move_factor", std::make_shared()} + {"move_factor", std::make_shared()}, })); + // TODO: Add string column with custom volume-type-specific options setInMemoryMetadata(storage_metadata); } @@ -45,6 +50,7 @@ Pipes StorageSystemStoragePolicies::read( MutableColumnPtr col_volume_name = ColumnString::create(); MutableColumnPtr col_priority = ColumnUInt64::create(); MutableColumnPtr col_disks = ColumnArray::create(ColumnString::create()); + MutableColumnPtr col_volume_type = ColumnString::create(); MutableColumnPtr col_max_part_size = ColumnUInt64::create(); MutableColumnPtr col_move_factor = ColumnFloat32::create(); @@ -61,6 +67,7 @@ Pipes StorageSystemStoragePolicies::read( for (const auto & disk_ptr : volumes[i]->getDisks()) disks.push_back(disk_ptr->getName()); col_disks->insert(disks); + col_volume_type->insert(volumeTypeToString(volumes[i]->getType())); col_max_part_size->insert(volumes[i]->max_data_part_size); col_move_factor->insert(policy_ptr->getMoveFactor()); } @@ -71,6 +78,7 @@ Pipes StorageSystemStoragePolicies::read( res_columns.emplace_back(std::move(col_volume_name)); res_columns.emplace_back(std::move(col_priority)); res_columns.emplace_back(std::move(col_disks)); + res_columns.emplace_back(std::move(col_volume_type)); res_columns.emplace_back(std::move(col_max_part_size)); res_columns.emplace_back(std::move(col_move_factor)); diff --git a/src/Storages/tests/get_abandonable_lock_in_all_partitions.cpp b/src/Storages/tests/get_abandonable_lock_in_all_partitions.cpp index 533db3236fd..7f50041e68e 100644 --- a/src/Storages/tests/get_abandonable_lock_in_all_partitions.cpp +++ b/src/Storages/tests/get_abandonable_lock_in_all_partitions.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include #include @@ -7,7 +5,6 @@ #include #include -#include #include diff --git a/src/Storages/tests/get_current_inserts_in_replicated.cpp b/src/Storages/tests/get_current_inserts_in_replicated.cpp index f1a87b5ca05..fa998d20f66 100644 --- a/src/Storages/tests/get_current_inserts_in_replicated.cpp +++ b/src/Storages/tests/get_current_inserts_in_replicated.cpp @@ -4,10 +4,8 @@ #include #include #include -#include #include -#include #include diff --git a/src/Storages/tests/gtest_SplitTokenExtractor.cpp b/src/Storages/tests/gtest_SplitTokenExtractor.cpp index cb801cff808..d2c1c3ebd76 100644 --- a/src/Storages/tests/gtest_SplitTokenExtractor.cpp +++ b/src/Storages/tests/gtest_SplitTokenExtractor.cpp @@ -1,7 +1,6 @@ #include #include -#include #include diff --git a/src/Storages/tests/gtest_storage_log.cpp b/src/Storages/tests/gtest_storage_log.cpp index 13c96fbab54..912aad81366 100644 --- a/src/Storages/tests/gtest_storage_log.cpp +++ b/src/Storages/tests/gtest_storage_log.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include diff --git a/src/Storages/tests/merge_selector.cpp b/src/Storages/tests/merge_selector.cpp index caa795297e1..b4b668f1b02 100644 --- a/src/Storages/tests/merge_selector.cpp +++ b/src/Storages/tests/merge_selector.cpp @@ -2,7 +2,6 @@ #include #include #include -#include /** This program tests merge-selecting algorithm. diff --git a/src/Storages/tests/transform_part_zk_nodes.cpp b/src/Storages/tests/transform_part_zk_nodes.cpp index 35e44bb9446..3cbcc76190e 100644 --- a/src/Storages/tests/transform_part_zk_nodes.cpp +++ b/src/Storages/tests/transform_part_zk_nodes.cpp @@ -1,6 +1,4 @@ #include -#include -#include #include #include #include diff --git a/tests/integration/runner b/tests/integration/runner index a009a1ce647..6369ebeea3e 100755 --- a/tests/integration/runner +++ b/tests/integration/runner @@ -14,9 +14,21 @@ DEFAULT_CLICKHOUSE_ROOT = os.path.abspath(os.path.join(CUR_FILE_DIR, "../../")) CURRENT_WORK_DIR = os.getcwd() CONTAINER_NAME = "clickhouse_integration_tests" +CONFIG_DIR_IN_REPO = "programs/server" +INTERGATION_DIR_IN_REPO = "tests/integration" + DIND_INTEGRATION_TESTS_IMAGE_NAME = "yandex/clickhouse-integration-tests-runner" def check_args_and_update_paths(args): + if args.clickhouse_root: + if not os.path.isabs(args.clickhouse_root): + CLICKHOUSE_ROOT = os.path.abspath(args.clickhouse_root) + else: + CLICKHOUSE_ROOT = args.clickhouse_root + else: + logging.info("ClickHouse root is not set. Will use {}".format(DEFAULT_CLICKHOUSE_ROOT)) + CLICKHOUSE_ROOT = DEFAULT_CLICKHOUSE_ROOT + if not os.path.isabs(args.binary): args.binary = os.path.abspath(os.path.join(CURRENT_WORK_DIR, args.binary)) @@ -25,15 +37,31 @@ def check_args_and_update_paths(args): elif not os.path.isabs(args.bridge_binary): args.bridge_binary = os.path.abspath(os.path.join(CURRENT_WORK_DIR, args.bridge_binary)) - if not os.path.isabs(args.configs_dir): - args.configs_dir = os.path.abspath(os.path.join(CURRENT_WORK_DIR, args.configs_dir)) + if args.base_configs_dir: + if not os.path.isabs(args.base_configs_dir): + args.base_configs_dir = os.path.abspath(os.path.join(CURRENT_WORK_DIR, args.base_configs_dir)) + else: + args.base_configs_dir = os.path.abspath(os.path.join(CLICKHOUSE_ROOT, CONFIG_DIR_IN_REPO)) + logging.info("Base configs dir is not set. Will use {}".format(args.base_configs_dir)) - if not os.path.isabs(args.clickhouse_root): - args.clickhouse_root = os.path.abspath(os.path.join(CURRENT_WORK_DIR, args.clickhouse_root)) + if args.cases_dir: + if not os.path.isabs(args.cases_dir): + args.cases_dir = os.path.abspath(os.path.join(CURRENT_WORK_DIR, args.cases_dir)) + else: + args.cases_dir = os.path.abspath(os.path.join(CLICKHOUSE_ROOT, INTERGATION_DIR_IN_REPO)) + logging.info("Cases dir is not set. Will use {}".format(args.cases_dir)) - for path in [args.binary, args.configs_dir, args.clickhouse_root]: + logging.info("base_configs_dir: {}, binary: {}, cases_dir: {} ".format(args.base_configs_dir, args.binary, args.cases_dir)) + + for path in [args.binary, args.base_configs_dir, args.cases_dir, CLICKHOUSE_ROOT]: if not os.path.exists(path): - raise Exception("Path {} doesn't exists".format(path)) + raise Exception("Path {} doesn't exist".format(path)) + + if not os.path.exists(os.path.join(args.base_configs_dir, "config.xml")): + raise Exception("No configs.xml in {}".format(args.base_configs_dir)) + + if not os.path.exists(os.path.join(args.base_configs_dir, "users.xml")): + raise Exception("No users.xml in {}".format(args.base_configs_dir)) def docker_kill_handler_handler(signum, frame): subprocess.check_call('docker kill $(docker ps -a -q --filter name={name} --format="{{{{.ID}}}}")'.format(name=CONTAINER_NAME), shell=True) @@ -41,6 +69,17 @@ def docker_kill_handler_handler(signum, frame): signal.signal(signal.SIGINT, docker_kill_handler_handler) +# Integration tests runner should allow to run tests on several versions of ClickHouse. +# Integration tests should be portable. +# To run integration tests following artfacts should be sufficient: +# - clickhouse binaries (env CLICKHOUSE_TESTS_SERVER_BIN_PATH or --binary arg) +# - clickhouse default configs(config.xml, users.xml) from same version as binary (env CLICKHOUSE_TESTS_BASE_CONFIG_DIR or --base-configs-dir arg) +# - odbc bridge binary (env CLICKHOUSE_TESTS_ODBC_BRIDGE_BIN_PATH or --bridge-binary arg) +# - tests/integration directory with all test cases and configs (env CLICKHOUSE_TESTS_INTEGRATION_PATH or --cases-dir) +# +# 1) --clickhouse-root is only used to determine other paths on default places +# 2) path of runner script is used to determine paths for trivial case, when we run it from repository + if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s') parser = argparse.ArgumentParser(description="ClickHouse integration tests runner") @@ -48,7 +87,7 @@ if __name__ == "__main__": parser.add_argument( "--binary", default=os.environ.get("CLICKHOUSE_TESTS_SERVER_BIN_PATH", os.environ.get("CLICKHOUSE_TESTS_CLIENT_BIN_PATH", "/usr/bin/clickhouse")), - help="Path to clickhouse binary") + help="Path to clickhouse binary. For example /usr/bin/clickhouse") parser.add_argument( "--bridge-binary", @@ -56,14 +95,18 @@ if __name__ == "__main__": help="Path to clickhouse-odbc-bridge binary. Defaults to clickhouse-odbc-bridge in the same dir as clickhouse.") parser.add_argument( - "--configs-dir", - default=os.environ.get("CLICKHOUSE_TESTS_BASE_CONFIG_DIR", os.path.join(DEFAULT_CLICKHOUSE_ROOT, "programs/server")), - help="Path to clickhouse configs directory") + "--base-configs-dir", + default=os.environ.get("CLICKHOUSE_TESTS_BASE_CONFIG_DIR"), + help="Path to clickhouse base configs directory with config.xml/users.xml") + + parser.add_argument( + "--cases-dir", + default=os.environ.get("CLICKHOUSE_TESTS_INTEGRATION_PATH"), + help="Path to integration tests cases and configs directory. For example tests/integration in repository") parser.add_argument( "--clickhouse-root", - default=DEFAULT_CLICKHOUSE_ROOT, - help="Path to repository root folder") + help="Path to repository root folder. Used to take configuration from repository default paths.") parser.add_argument( "--command", @@ -104,13 +147,14 @@ if __name__ == "__main__": tty = "-it" cmd = "docker run {net} {tty} --rm --name {name} --privileged --volume={bridge_bin}:/clickhouse-odbc-bridge --volume={bin}:/clickhouse \ - --volume={cfg}:/clickhouse-config --volume={pth}:/ClickHouse --volume={name}_volume:/var/lib/docker -e PYTEST_OPTS='{opts}' {img} {command}".format( + --volume={base_cfg}:/clickhouse-config --volume={cases_dir}:/ClickHouse/tests/integration \ + --volume={name}_volume:/var/lib/docker -e PYTEST_OPTS='{opts}' {img} {command}".format( net=net, tty=tty, bin=args.binary, bridge_bin=args.bridge_binary, - cfg=args.configs_dir, - pth=args.clickhouse_root, + base_cfg=args.base_configs_dir, + cases_dir=args.cases_dir, opts=' '.join(args.pytest_args), img=DIND_INTEGRATION_TESTS_IMAGE_NAME + ":" + args.docker_image_version, name=CONTAINER_NAME, diff --git a/tests/integration/test_multiple_disks/test.py b/tests/integration/test_multiple_disks/test.py index cbfeb9dac3a..d00450bf245 100644 --- a/tests/integration/test_multiple_disks/test.py +++ b/tests/integration/test_multiple_disks/test.py @@ -73,6 +73,7 @@ def test_system_tables(start_cluster): "volume_name": "main", "volume_priority": "1", "disks": ["jbod1"], + "volume_type": "JBOD", "max_data_part_size": "0", "move_factor": 0.1, }, @@ -81,6 +82,7 @@ def test_system_tables(start_cluster): "volume_name": "external", "volume_priority": "2", "disks": ["external"], + "volume_type": "JBOD", "max_data_part_size": "0", "move_factor": 0.1, }, @@ -89,6 +91,7 @@ def test_system_tables(start_cluster): "volume_name": "m", "volume_priority": "1", "disks": ["jbod1"], + "volume_type": "JBOD", "max_data_part_size": "0", "move_factor": 0.1, }, @@ -97,6 +100,7 @@ def test_system_tables(start_cluster): "volume_name": "e", "volume_priority": "2", "disks": ["external"], + "volume_type": "JBOD", "max_data_part_size": "0", "move_factor": 0.1, }, @@ -105,6 +109,7 @@ def test_system_tables(start_cluster): "volume_name": "main", "volume_priority": "1", "disks": ["jbod1", "jbod2"], + "volume_type": "JBOD", "max_data_part_size": "10485760", "move_factor": 0.1, }, @@ -113,6 +118,7 @@ def test_system_tables(start_cluster): "volume_name": "external", "volume_priority": "2", "disks": ["external"], + "volume_type": "JBOD", "max_data_part_size": "0", "move_factor": 0.1, }, @@ -121,6 +127,7 @@ def test_system_tables(start_cluster): "volume_name": "main", "volume_priority": "1", "disks": ["jbod1"], + "volume_type": "JBOD", "max_data_part_size": "0", "move_factor": 0.7, }, @@ -129,6 +136,7 @@ def test_system_tables(start_cluster): "volume_name": "external", "volume_priority": "2", "disks": ["external"], + "volume_type": "JBOD", "max_data_part_size": "0", "move_factor": 0.7, }, @@ -137,6 +145,7 @@ def test_system_tables(start_cluster): "volume_name": "small", "volume_priority": "1", "disks": ["default"], + "volume_type": "JBOD", "max_data_part_size": "2097152", "move_factor": 0.1, }, @@ -145,6 +154,7 @@ def test_system_tables(start_cluster): "volume_name": "big", "volume_priority": "2", "disks": ["external"], + "volume_type": "JBOD", "max_data_part_size": "20971520", "move_factor": 0.1, }, @@ -153,6 +163,7 @@ def test_system_tables(start_cluster): "volume_name": "special_warning_zero_volume", "volume_priority": "1", "disks": ["default"], + "volume_type": "JBOD", "max_data_part_size": "0", "move_factor": 0.1, }, @@ -161,6 +172,7 @@ def test_system_tables(start_cluster): "volume_name": "special_warning_default_volume", "volume_priority": "2", "disks": ["external"], + "volume_type": "JBOD", "max_data_part_size": "0", "move_factor": 0.1, }, @@ -169,6 +181,7 @@ def test_system_tables(start_cluster): "volume_name": "special_warning_small_volume", "volume_priority": "3", "disks": ["jbod1"], + "volume_type": "JBOD", "max_data_part_size": "1024", "move_factor": 0.1, }, @@ -177,6 +190,7 @@ def test_system_tables(start_cluster): "volume_name": "special_warning_big_volume", "volume_priority": "4", "disks": ["jbod2"], + "volume_type": "JBOD", "max_data_part_size": "1024000000", "move_factor": 0.1, }, diff --git a/tests/integration/test_odbc_interaction/test.py b/tests/integration/test_odbc_interaction/test.py index b93619d06b5..46845802083 100644 --- a/tests/integration/test_odbc_interaction/test.py +++ b/tests/integration/test_odbc_interaction/test.py @@ -251,8 +251,11 @@ def test_bridge_dies_with_parent(started_cluster): clickhouse_pid = node1.get_process_pid("clickhouse server") time.sleep(1) - time.sleep(1) # just for sure, that odbc-bridge caught signal - bridge_pid = node1.get_process_pid("odbc-bridge") + for i in range(5): + time.sleep(1) # just for sure, that odbc-bridge caught signal + bridge_pid = node1.get_process_pid("odbc-bridge") + if bridge_pid is None: + break if bridge_pid: out = node1.exec_in_container(["gdb", "-p", str(bridge_pid), "--ex", "thread apply all bt", "--ex", "q"], privileged=True, user='root') diff --git a/tests/performance/set_index.xml b/tests/performance/set_index.xml index 6a3438bc64a..76f1087a1bf 100644 --- a/tests/performance/set_index.xml +++ b/tests/performance/set_index.xml @@ -28,6 +28,17 @@ '37674', '44977', '54370', '97381', '60218', '2423', '99591', '69913', '26507', '19708', '6279', '58955', '20126', '1495', '57894', '7638', '38700', '77148', '36844', '7539', '91452', '6914', '74349', '66850', '49104', '6516', '58535', '20851', '27859', '32881', '72919', '28203', '32882', '2419', '77583', '63822', '37703', '66793', '65784', '62281', '55867', '70703', '89344', '1498', '33770', '87176', '95636', '64891', '90736', '95521', '10989', '5237', '99010', '21106', '11422', '1831', '67239', '52557', '36468', '71713', '39637', '49574', '50455', '14953', '96900', '70852', '96982', '4341', '44585', '95651', '79669', '29652', '87294', '74692', '16221', '768', '35380', '21352', '50907', '27259', '11718', '5017', '55964', '94137', '52347', '10595', '12968', '85602', '97965', '18836', '90511', '70960', '97336', '44575', '23791', '42195', '64776', '29363', '42379', '1805', '28919', '6772', '78143', '54797', '27362', '56149', '59048', '38567', '6339', '27787', '42167', '45990', '95532', '54839', '26572', '38496', '89797', '6634', '16468', '24898', '66814', '98126', '31762', '36133', '64539', '43167', '87022', '61295', '30364', '89249', '25756', '63570', '91484', '10564', '79648', '5756', '41376', '61897', '40388', '88927', '62891', '79708', '25495', '22204', '33892', '36871', '19879', '58646', '57061', '73100', '75831', '20029', '67462', '54675', '7766', '2409', '24506', '7877', '11720', '86252', '9897', '8080', '70684', '74497', '2242', '24604', '31969', '83999', '56635', '5283', '64971', '79152', '27470', '89042', '22835', '21476', '50292', '56081', '96342', '32763', '84487', '64856', '79152', '64656', '72169', '69971', '93094', '52804', '80917', '53152', '56016', '28496', '79110', '17133', '12581', '91742', '78929', '2676', '46700', '59528', '93808', '4535', '54035', '40161', '62796', '3598', '97088', '13599', '36337', '73395', '17494', '86275', '62058', '61937', '87747', '94883', '90677', '88544', '72553', '50210', '75481', '64378', '74464', '21659', '30970', '71989', '84846', '72289', '88716', '39143', '8487', '4912', '91013', '18623', '19122', '36507', '76438', '7516', '67970', '72350', '69873', '33635', '55983', '69008', '49545', '3134', '60056', '52509', '63304', '15560', '23651', '81090', '7027', '8317', '33060', '37295', '51961', '53037', '97431', '40512', '23536', '25168', '78455', '85613', '12304', '40733', '99890', '51238', '55439', '96201', '73559', '92533', '90173', '16721', '6078', '29854', '38894', '31117', '63040', '86795', '81786', '21149', '38998', '61811', '48622', '73019', '59296', '13576', '92559', '36300', '77294', '26794', '50912', '98380', '13176', '57746', '75286', '15330', '40921', '7337', '4664', '20384', '4674', '44516', '27633', '31950', '88210', '54536', '9839', '80137', '77491', '18434', '45152', '96942', '41005', '76103', '34825', '86869', '14772', '13384', '21051', '37348', '34434', '97210', '54960', '26598', '60981', '41889', '6446', '64492', '95310', '86236', '81885', '35684', '16539', '98476', '32028', '96470', '6318', '99576', '93935', '48609', '86090', '2476', '65576', '80636', '44817', '99646', '98963', '20486', '26261', '27334', '72946', '82023', '33506', '80193', '13762', '98133', '21134', '33268', '63477', '74609', '30454', '51477', '93391', '96805', '68653', '2714', '63642', '51520', '22972', '13305', '96058', '42336', '74461', '31597', '12050', '81712', '37977', '25718', '4834', '56608', '75731', '406', '28585', '63924', '23702', '29849', '16941', '91921', '65842', '76525', '68534', '50902', '17609', '23852', '53703', '31286', '58526', '9633', '87596', '10654', '2085', '52766', '22135', '76524', '32295', '90072', '70078', '77786', '93741', '87320', '70309', '44024', '95286', '12361', '29682', '59766', '26685', '90686', '81691', '49704', '23431', '53955', '39023', '47261', '1530', '58265', '80065', '95620', '90621', '63760', '90676', '81653', '36397', '20252', '81754', '20256', '67098', '7838', '49408', '88400', '87941', '84533', '6570', '22567', '18850', '55472', '40129', '48425', '23497', '39308', '34698', '53092', '89480', '47785', '57282', '25508', '19006', '50604', '86917', '9436', '88921', '3168', '70537', '3185', '34988', '5462', '69482', '45768', '91955', '56898', '15307', '99731', '89292', '19356', '20646', '66712', '7281', '12856', '31174', '19577', '8726', '62971', '33008', '37118', '59055', '84101', '68445', '91957', '47526', '15627', '79914', '20013', '26147', '80821', '56372', '74205', '28531', '25352', '51775', '93948', '55212', '17863', '91521', '74911', '88160', '2360', '98260', '18294', '62402', '84268', '9580', '42668', '1467', '40059', '5221', '4216', '9917', '35420', '16496', '34369', '50253', '95234', '95114', '84193', '28322', '37031', '81284', '88628', '36782', '42572', '73347', '66188', '43342', '77285', '16513', '89064', '63066', '72645', '67075', '48208', '18181', '77898', '65795', '53707', '39856', '92883', '92567', '49733', '30236', '10273', '53029', '69773', '78379', '72108', '47696', '97557', '95184', '14688', '29853', '62694', '70431', '88435', '58799', '21883', '99866', '69178', '55870', '14414', '85274', '27321', '55555', '613', '15067', '88217', '73655', '99548', '13631', '78789', '36690', '7952', '60830', '77438', '40059', '95602', '43097', '3429', '93731', '90537', '2932', '35702', '16125', '6652', '39632', '39349', '9910', '38103', '78608', '73565', '48556', '28978', '7128', '82326', '53980', '28059', '28212', '87101', '77752', '99170', '56753', '30484', '71470', '32607', '24674', '32687', '25098', '94712', '64024', '48239', '90408', '17316', '99243', '3656', '67402', '48009', '98427', '52800', '56024', '4417', '89747', '93338', '18758', '56411', '44810', '82456', '30808', '75470', '67115', '66876', '53906', '78403', '56059', '34383', '60056', '89136', '7237', '11129', '21351', '78662', '43606', '37454', '45465', '9292', '38099', '81699', '50195', '49368', '47503', '44605', '6523', '81478', '37910', '397', '20256', '6835', '2787', '80383', '4241', '65986', '83870', '21205', '10879', '26593', '44357', '72604', '56131', '43423', '80206', '26240', '87198', '99445', '53504', '10632', '2465', '31793', '89575', '64184', '39988', '60049', '87100', '37151', '61585', '82180', '52065', '72519', '72935', '3201', '5862', '20560', '95339', '21661', '17533', '17182', '71189', '91564', '57999', '35490', '94773', '95056', '51583', '59394', '10727', '8655', '48123', '10701', '25314', '20100', '6533', '46435', '43188', '23001', '23018', '76637', '32018', '36603', '18701', '9550', '61550', '47541', '36500', '67507', '81574', '95490', '69169', '32584', '30045', '64699', '83539', '89396', '42517', '61979', '41528', '8271', '88377', '61423', '1158', '89724', '70789', '14886', '64823', '56675', '97747', '23990', '58495', '82064', '17062', '90258', '86854', '93304', '12925', '49975', '45074', '87155', '72223', '67344', '42733', '42516', '40110', '15444', '88285', '39371', '23198', '61544', '90205', '6192', '15718', '19803', '92712', '20081', '31397', '5555', '70463', '19521', '80401', '74097', '32060', '26495', '20507', '40473', '1449', '57215', '46142', '39303', '50359', '35898', '46908', '90752', '7823', '27416', '73770', '98790', '17907', '29999', '76417', '49926', '76752', '21608', '26524', '88209', '6000', '88897', '19541', '41451', '59538', '56560', '1456', '67828', '82407', '45722', '93344', '54279', '78594', '38354', '93807', '10929', '91560', '60681', '70615', '32527', '10108', '48303', '63134', '28500', '18257', '57081', '24801', '99077', '52197', '15390', '52300', '57116', '417', '7503', '20054', '75315', '81359', '69091', '18853', '2465', '25600', '13522', '74575', '12661', '83071', '15191', '27543', '21730', '60853', '18961', '14773', '89185', '33694', '51143', '1449', '68831', '78062', '65173', '32697', '41674', '9429', '22156', '96022', '46305', '97534', '5685', '48870', '89988', '20686', '66705', '6865', '94250', '16872', '13178', '7420', '73531', '92723', '60620', '48843', '74207', '60016', '50943', '62699', '63507', '76537', '87066', '76922', '24711', '34809', '5021', '31293', '53854', '77607', '52322', '10934', '50284', '87804', '36730', '86946', '80749', '43325', '97958', '7362', '39582', '10042', '42053', '66236', '69931', '23463', '87996', '33563', '4468', '32905', '50815', '79478', '28658', '46018', '23186', '26080', '13494', '6237', '42762', '86440', '77407', '10426', '62902', '73251', '36861', '92357', '98754', '1839', '46391', '11420', '27132', '93028', '39609', '42015', '68218', '54228', '5456', '38705', '64307', '49483', '878', '54360', '54480', '66684', '55089', '4537', '82073', '72602', '96238', '56708', '58625', '32991', '74205', '72868', '79086', '64250', '56376', '10621', '76607', '47706', '72760', '70303', '60715', '14644', '44186', '36264', '29489', '14184', '62699', '30567', '16700', '31222', '15650', '1500', '22950', '54628', '41004', '96094', '70028', '74178', '65328', '26605', '63076', '75271', '79285', '8151', '42101', '56362', '25961', '87864', '972', '29510', '2747', '8877', '9780', '61052', '84105', '15573', '27475', '44570', '25334', '18517', '44237', '84094', '67524', '76761', '65678', '79284', '2462', '42631', '22696', '19223', '29728', '67742', '11883', '59027', '12377', '80538', '2165', '17377', '15030', '49838', '23920', '26025', '68179', '75894', '43783', '97106', '75558', '35528', '52081', '16951', '68855', '402', '21459', '97550', '16948', '5369', '4641', '2663', '15233', '79974', '71093', '15234', '42690', '22322', '54282', '95845', '90010', '40530', '88298', '41885', '7079', '6098', '72786', '36603', '77378', '48393', '45723', '41996', '96025', '89297', '75586', '8422', '24360', '170', '46036', '46725', '67944', '74029', '73069', '45371', '99916', '71085', '42608', '89904', '6393', '51274', '42729', '58924', '82497', '64143', '88622', '18818', '89041', '56090', '21369', '78224', '90450', '45488', '58830', '4133', '98062', '81113', '11285', '51457', '3183', '38800', '65278', '42169', '28602', '52648', '44683', '75647', '11778', '32151', '33528', '23773', '68268', '23367', '70964', '23548', '35575', '67570', '77681', '74158', '25374', '62714', '43100', '4977', '51678', '83460', '29755', '15890', '64626', '54044', '14793', '64339', '94008', '97126', '49202', '33889', '12601', '12275', '56123', '94557', '68226', '67200', '9374', '70687', '29211', '8039', '14598', '74548', '37433', '98991', '29933', '37203', '23973', '96482', '64774', '58350', '61781', '31824', '57193', '26476', '21814', '32297', '32627', '44277', '33876', '55468', '81715', '82505', '61462', '20324', '84293', '40116', '51087', '43594', '6854', '59077', '39841', '26023', '22777', '66859', '82460', '89515', '41712', '33711', '71875', '10685', '12655', '50138', '31063', '37040', '95819', '38919', '27391', '29833', '34350', '65646', '7697', '2688', '41146', '13241', '50305', '86568', '24487', '78741', '96370', '21015', '31719', '39750', '25014', '72415', '8486', '90668', '51143', '49488', '21057', '92803', '53528', '39550', '76039', '44185', '32404', '30217', '19796', '38084', '49161', '80140', '20241', '39357', '68908', '93083', '77231', '6952', '36322', '50790', '623', '29730', '13616', '57546', '17434', '93811', '35148', '81419', '40250', '40329', '89126', '72402', '16053', '27107', '28919', '16829', '96582', '65057', '28416', '30801', '77742', '27420', '73118', '89352', '54706', '23035', '88413', '64608', '61930', '15037', '47327', '59596', '18700', '57576', '63628', '56823', '60091', '68209', '21001', '14962', '72257', '83802', '33721', '86343', '11133', '65737', '68477', '90725', '86869', '98403', '47393', '25356', '61372', '8873', '19888', '48836', '66005', '23531', '72520', '26461', '78508', '28213', '96394', '22983', '37856', '71814', '27425', '72753', '27511', '65471', '38592', '3683', '24652', '64505', '92543', '53201', '40639', '99542', '53425', '35321', '47669', '14134', '47727', '48202', '71931', '32119', '50086', '50266', '67159', '89317', '81905', '30315', '49154', '8690', '69365', '56881', '46473', '64100', '38365', '59377', '65630', '54871', '52745', '91536', '16106', '70066', '62063', '84530', '88103', '33599', '51063', '87299', '41880', '25335', '51252', '42788', '13568', '1721', '62424', '83308', '36787', '91536', '92555', '27600', '24030', '12267', '66336', '30242', '7183', '67624', '28471', '48593', '79766', '31178', '47818', '94522', '88855', '45262', '43670', '18065', '25062', '44558', '37189', '69225', '35216', '42683', '26289', '72816', '31947', '65871', '45715', '59452', '22014', '56669', '60331', '33450', '60601', '95047', '30789', '90107', '81565', '32266', '3252', '5446', '58756', '55370', '34034', '81071', '2560', '39054', '39564', '15010', '5389', '60002', '53320', '49545', '48444', '31415', '39278', '79879', '30148', '10186', '60358', '29011', '14419', '95159', '94815', '55251', '90910', '80582', '92304', '11697', '60061', '38577', '84439', '76196', '34542', '50963', '36294', '11123', '59763', '29873', '47383', '12979', '22119', '21723', '64725', '48377', '77132', '9817', '79920', '47653', '60069', '12924', '53808', '55962', '66969', '13757', '60615', '10994', '9138', '34119', '58436', '64407', '75170', '73524', '51864', '94183', '86847', '15585', '57616', '96267', '5340', '52929', '49096', '50291', '5559', '32382', '84077', '6598', '87921', '59719', '31726', '44772', '63373', '75420', '66829', '47275', '98264', '61387', '94945', '44540', '50098', '13078', '44729', '95332', '63555', '30782', '63203', '15071', '60996', '72812', '17418', '80215', '37610', '30670', '44674', '74822', '15471', '25236', '16266', '76213', '35820', '19567', '8715', '72003', '90606', '1434', '53545', '88170', '75014', '62287', '35436', '38669', '12927', '83877', '38622', '28313', '82884', '73969', '38671', '10450', '24158', '22941', '73162', '86548', '42482', '95315', '92016', '96156', '44012', '35962', '6366', '3881', '74300', '26248', '30182', '19164', '67105', '66771', '52587', '69894', '61820', '16551', '50743', '10096', '69030', '24451', '89165', '23929', '96291', '30685', '64413', '19913', '9049', '71383', '61684', '45384', '45927', '81840', '49521', '89594', '30055', '83430', '14930', '60316', '86585', '99375', '80170', '14207', '19584', '20067', '82874', '30159', '46647', '6942', '66777', '32638', '55662', '75470', '77622', '26893', '96149', '14373', '33252', '50574', '7945', '20696', '56662', '94348', '3384', '20956', '89668', '99052', '65131', '56847', '17589', '16419', '2670', '10705', '59587', '92902', '92424', '48570', '11034', '69149', '35733', '17315', '84966', '69353', '69590', '52834', '32561', '6049', '50156', '71676', '76423', '32361', '61509', '8845', '75709', '35956', '21912', '31188', '59083', '43459', '38614', '92206', '55645', '38737', '34193', '6451', '94163', '24326', '49976', '71600', '58024', '67160', '4365', '38270', '59558', '80834', '60739', '54318', '19738', '42196', '43191', '13463', '88914', '99239', '66869', '75691', '33085', '4323', '7170', '46184', '41423', '89835', '46877', '20349', '14365', '32727', '35322', '841', '23597', '43370', '57527', '73250', '32553', '71489', '44617', '98323', '37672', '59549', '96023', '63176', '13524', '15621', '30448', '28136', '45549', '3513', '64153', '19839', '24219', '41987', '51083', '90268', '52052', '31430', '4727', '99409', '43595', '82374', '61251', '51470', '66562', '98724', '23529', '53895', '67562', '87573', '89964', '30821', '15733', '33062', '86963', '33450', '75338', '32570', '14453', '38080', '36335', '84226', '52790', '42883', '61156', '42789', '57846', '60096', '29946', '80178', '15882', '1971', '60722', '62458', '8754', '59991', '89321', '584', '70565', '36458', '21226', '23561', '9837', '39364', '23065', '30675', '9306', '40085', '52082', '89976', '73283', '77851', '36174', '54470', '63250', '72111', '70853', '26723', '42590', '91230', '47512', '13983', '70898', '70927', '40721', '30642', '41628', '90010', '27306', '1933', '43304', '44499', '87890', '22201', '89249', '63935', '48438', '58588', '1061', '70061', '63075', '9676', '65820', '82156', '82668', '111', '54350', '10328', '23466', '98936', '18285', '53919', '32422', '84859', '58387', '24022', '32423', '6010', '56417', '49452', '69999', '14885', '47102', '59577', '24999', '75984', '96464', '59088', '85987', '71442', '88789', '4753', '8229', '76883', '15284', '90610', '40507', '78882', '55575', '25315', '7214', '70602', '4796', '35767', '54657', '42153', '16050', '93607', '99249', '77236', '59949', '52871', '47837', '33534', '30023', '89137', '99938', '35824', '50775', '30282', '82798', '53312', '65277', '68375', '91445', '58166', '43344', '6589', '82515', '34632', '78588', '152', '67554', '15877', '74334', '32783', '45147', '39483', '92067', '59029', '38298', '55229', '28268', '85140', '33451', '15424', '46695', '23201', '83329', '28372', '19518', '89198', '33305', '43892', '470', '37662', '9407', '14376', '80310', '21459', '72381', '80414', '88305', '69073', '63101', '91054', '47190', '48595', '24696', '41426', '35133', '94399', '21790', '55040', '73279', '20809', '67805', '94115', '58633', '78053', '89444', '4112', '8', '34517', '22106', '85934', '86814', '53333', '93437', '85062', '32791', '72744', '99843', '51161', '22730', '34908', '82918', '92566', '22467', '41226', '98518', '29235', '94042', '84371', '79100', '25214', '7764', '59427', '47891', '61092', '23775', '13641', '30837', '77377', '43032', '38441', '29462', '20300', '19070', '20982', '73987', '87836', '68062', '6419', '51563', '40084', '85694', '86677', '47142', '27222', '17844', '19158', '45120', '88524', '74724', '73229', '42470', '38751', '1132', '28603', '61188', '55021', '88825', '58005', '62411', '8843', '94852', '93664', '39253', '27473', '247', '43824', '1804', '8905', '11509', '95659', '7811', '80691', '15779', '49794', '8991', '76099', '29223', '36060', '85399', '41369', '22885', '38473', '22376', '50446', '89578', '25818', '61333', '78787', '47605', '83654', '99068', '52120', '48367', '86381', '19803', '72600', '31998', '37755', '88031', '83969', '42319', '27974', '35780', '93662', '46808', '60529', '15491', '10447', '48829', '33886', '68333', '44855', '86554', '64794', '66376', '58222', '14021', '52043', '56375', '1300', '38105', '89159', '97456', '26800', '93124', '3673', '32279', '30658', '84475', '3708', '93952', '39245', '91980', '55333', '79440', '64407', '46559', '60759', '10688', '49872', '45810', '87405', '66932', '56530', '57751', '9619', '27361', '6356', '65848', '7524', '20273', '22362', '20504', '28042', '39475', '51677', '85733', '32426', '54558', '17222', '56485', '34928', '90917', '70528', '51732', '61014', '98420', '67265', '41383', '3883', '47642', '53324', '93679', '93088', '57534', '44449', '46779', '81482', '54279', '80135', '11216', '92545', '18426', '96005', '57801', '21898', '5104', '83467', '72015', '43783', '89674', '57468', '96686', '95167', '38507', '95187', '64923', '71214', '42834', '93219', '47342', '24476', '84834', '29080', '86533', '30687', '68400', '26933', '37396', '65169', '89767', '20642', '53843', '85167', '77306', '46723', '68501', '4243', '35044', '15950', '40388', '53630', '76125', '10816', '83285', '4120', '11402', '91344', '95169') + + SELECT toString(rand()) IN tuple('41577', '83972', '51697', '50014', '37553', '93459', '87438', '95971', '83186', '74326', '67871', '50406', '83678', '29655', '18580', '83905', '61518', '29059', '56700', '82787', '98672', '30884', '81822', '39850', '80852', '57627', '91346', '64522', '17781', '49467', '41099', '41929', '85618', '91389', '68564', '91769', '81219', '52218', '37220', '97097', '2129', '9886', '52049', '34847', '25364', '36429', '76897', '71868', '58121', '71199', '84819', '69991', '34046', '64507', '34892', '24228', '36986', '28588', '51159', '53444', '80531', '9941', '20256', '48103', '32565', '62890', '5379', '60302', '46434', '3205', '18821', '31030', '19794', '71557', '71703', '15024', '14004', '82164', '95659', '40227', '83358', '24395', '9610', '19814', '48491', '66412', '16012', '71586', '42143', '51103', '24463', '89949', '35694', '39193', '63904', '40489', '77144', '94014', '84836', '9980', '46554', '43905', '25588', '25205', '72624', '10249', '35888', '98478', '99030', '26834', '31', '81499', '14847', '82997', '92357', '92893', '17426', '56630', '22252', '68119', '62710', '8740', '82144', '79916', '23391', '30192', '99271', '96435', '44237', '98327', '69481', '16691', '13643', '84554', '38571', '70926', '99283', '79000', '20926', '86495', '4834', '1222', '39486', '57697', '58002', '40790', '15623', '3999', '31515', '12694', '26143', '35951', '54085', '97534', '35329', '73535', '88715', '29572', '75799', '45166', '32066', '48023', '69523', '93150', '8740', '96790', '15534', '63252', '5142', '67045', '93992', '16663', '292', '63924', '6588', '12190', '31506', '69590', '35394', '55168', '65223', '79183', '32600', '69676', '28316', '72111', '53531', '15073', '41127', '73451', '24725', '61647', '65315', '41143', '26493', '95608', '34407', '76098', '53105', '83691', '48755', '35696', '62587', '81826', '3963', '45766', '82751', '12430', '97685', '29919', '78155', '71636', '50215', '89734', '9892', '47151', '54855', '3428', '9712', '52592', '2403', '79602', '81243', '79859', '57361', '82000', '42107', '28860', '99591', '28296', '57337', '64969', '32332', '25535', '30924', '21313', '32554', '17342', '87311', '19825', '24898', '61323', '83209', '79322', '79009', '50746', '33396', '62033', '16548', '17427', '24073', '34640', '52368', '4724', '80408', '40', '33787', '16666', '19665', '86751', '27264', '2241', '88134', '53566', '10589', '79711', '92823', '58972', '91767', '60885', '51659', '7867', '96849', '30360', '20914', '9584', '1250', '22871', '23282', '99312', '4683', '33429', '68361', '82614', '81440', '47863', '69790', '11968', '75210', '66854', '37002', '61142', '71514', '1588', '42336', '11069', '26291', '2261', '71056', '13492', '9133', '91216', '72207', '71586', '86535', '83898', '24392', '45384', '48545', '61972', '503', '80180', '35834', '97025', '70411', '55039', '35430', '27631', '82533', '96831', '74077', '42533', '14451', '26943', '53783', '69489', '71969', '8432', '37230', '61348', '19472', '59115', '9886', '50951', '57109', '7141', '1902', '84130', '4323', '55889', '47784', '2220', '75988', '66988', '63721', '8131', '95601', '95207', '2311', '26541', '50991', '6717', '2969', '71857', '51034', '65958', '94716', '90275', '21012', '46859', '7984', '31131', '46457', '69578', '44540', '7294', '80117', '9925', '60155', '90608', '82684', '32193', '87071', '28006', '87604', '24501', '79087', '2848', '29237', '11221', '81319', '40966', '87641', '35325', '78705', '88636', '78717', '62831', '56390', '99271', '43821', '14453', '17923', '62695', '77322', '21038', '67677', '41271', '4376', '65426', '46091', '19887', '97251', '55583', '58763', '3826', '35037', '73533', '64267', '82319', '9836', '42622', '96829', '16363', '10455', '49290', '99992', '98229', '66356', '59087', '73998', '25986', '4279', '56790', '69540', '588', '36620', '60358', '45056', '89297', '42740', '8323', '19245', '82417', '41431', '699', '11554', '73910', '44491', '56019', '68901', '45816', '68126', '89379', '23885', '13263', '56395', '73130', '19089', '23771', '10335', '48547', '16903', '6453', '33560', '89668', '38159', '43177', '90655', '49712', '62', '66920', '34180', '12150', '48564', '39538', '85026', '87195', '14928', '8956', '71157', '53287', '39161', '67583', '83309', '92054', '86977', '56188', '15229', '88170', '60894', '58497', '89254', '40082', '86890', '60161', '97291', '45878', '23368', '14577', '92870', '37017', '97356', '99426', '76061', '89186', '99751', '85153', '61580', '39360', '90107', '25603', '26798', '76224', '6469', '7912', '69838', '16404', '67497', '28965', '80836', '80365', '91249', '48713', '17113', '33090', '40793', '70450', '66689', '83698', '17802', '43869', '13355', '18959', '79411', '87930', '9265', '37504', '44876', '97234', '94149', '35040', '22049', '49248', '6535', '36080', '28346', '94437', '78319', '17961', '89056', '56161', '35810', '41632', '45494', '53351', '89729', '99510', '51584', '59688', '6193', '70809', '51093', '92589', '90247', '34910', '78235', '17362', '49423', '63324', '525', '37638', '72325', '89356', '15298', '59116', '17848', '65429', '27029', '84781', '70247', '8825', '35082', '70451', '22522', '58125', '91879', '90531', '2478', '463', '37902', '54405', '87267', '72688', '22803', '33134', '35177', '84551', '44974', '88375', '76407', '27774', '33849', '19915', '82014', '80434', '26380', '48777', '53811', '14838', '26829', '56441', '99869', '49574', '85476', '19723', '16907', '4018', '37338', '78510', '47912', '13030', '65277', '95716', '67363', '21393', '89887', '78842', '81650', '903', '17436', '30704', '49223', '27198', '25500', '52214', '54258', '70082', '53950', '49312', '43615', '99473', '94348', '53661', '96213', '96346', '62010', '38268', '32861', '75660', '10392', '89491', '68335', '29817', '88706', '24184', '36298', '43440', '21626', '26535', '44560', '46363', '12534', '99070', '95606', '33714', '73070', '8303', '29853', '23014', '99982', '4530', '14955', '45803', '50', '90750', '30394', '81276', '95563', '47314', '58520', '91299', '88944', '54402', '67405', '29253', '47079', '71734', '99728', '17652', '13307', '35556', '18962', '26780', '17771', '53712', '60055', '37628', '35830', '90739', '61151', '41309', '27652', '3051', '53167', '98417', '19382', '36833', '75085', '65374', '87732', '30352', '31776', '32765', '97565', '92199', '49050', '29503', '51024', '18834', '8515', '24069', '96216', '10777', '90680', '18974', '68884', '85305', '36007', '56707', '4212', '47352', '34426', '13185', '92939', '95782', '70577', '58080', '98279', '3906', '5065', '56896', '16382', '31273', '17117', '98602', '12786', '24086', '63970', '72756', '35798', '82367', '7356', '53398', '68503', '2962', '16425', '67334', '68461', '65439', '15620', '70906', '29649', '46461', '74602', '38012', '71714', '16825', '89480', '53386', '88532', '35104', '28556', '82120', '23155', '23347', '24797', '60061', '54962', '99427', '82248', '82447', '39968', '63727', '27431', '81511', '91168', '71425', '80740', '84127', '40717', '15503', '15419', '46594', '61263', '19212', '53175', '70724', '74445', '23034', '71818', '40246', '18886', '53066', '4880', '83701', '86107', '87862', '44751', '392', '73440', '90291', '93395', '20894', '38463', '32664', '55158', '20090', '50004', '79070', '98471', '85478', '96615', '68149', '78334', '97752', '73207', '71678', '91238', '96757', '82598', '194', '35797', '45120', '60782', '28721', '17676', '78066', '60957', '11826', '51563', '50516', '16485', '47053', '31738', '48923', '23554', '96850', '42033', '73701', '78607', '45979', '54571', '12415', '31693', '15356', '36902', '9126', '3767', '3295', '90402', '24005', '95350', '67033', '49137', '72606', '51899', '17522', '31957', '44641', '53982', '23767', '68257', '15766', '19995', '2107', '48788', '11765', '91055', '46576', '54651', '50381', '62827', '73636', '46606', '98753', '37631', '70441', '87916', '66983', '33870', '31125', '12904', '57040', '4874', '58632', '42037', '18782', '5998', '18974', '57949', '81010', '90407', '99874', '20462', '89949', '10952', '71454', '95130', '46115', '3518', '13384', '69039', '79482', '22076', '59782', '32042', '40930', '60243', '29298', '6790', '46985', '44398', '85631', '14380', '66179', '2629', '32126', '49833', '14118', '58492', '31493', '81172', '96638', '8745', '89663', '76842', '78633', '41373', '83721', '42886', '11123', '32739', '11051', '1303', '92314', '83324', '85600', '44276', '69064', '56125', '84650', '31028', '12628', '14502', '64764', '39405', '44855', '79046', '51716', '46824', '83389', '1941', '1257', '9280', '73176', '84729', '2579', '63366', '22606', '35541', '51096', '13447', '18355', '68037', '28436', '94116', '81070', '78355', '67897', '5296', '32742', '77645', '91853', '18767', '67949', '40963', '5792', '17278', '25597', '41884', '80829', '7099', '18645', '60295', '12082', '81800', '78415', '18082', '38789', '16295', '72377', '74949', '55583', '66853', '15402', '72977', '15123', '99434', '34999', '21687', '76049', '42987', '83748', '88256', '66688', '21766', '20304', '29271', '10069', '19822', '11792', '42526', '74143', '17289', '30253', '6367', '20888', '12975', '94073', '98639', '30134', '26320', '65507', '69002', '53120', '4550', '38893', '18954', '38283', '54863', '17698', '99670', '10521', '92467', '60994', '18052', '48673', '35811', '87282', '62706', '16061', '53112', '22652', '37780', '55662', '26331', '49410', '79074', '10623', '69577', '79613', '9491', '31229', '43922', '84231', '58409', '36386', '46875', '74431', '76735', '38776', '23350', '7314', '9079', '51519', '98544', '70216', '63380', '90381', '1295', '46901', '58225', '55339', '89918', '75522', '35431', '89460', '49552', '89302', '23068', '28493', '3042', '25194', '59520', '9810', '95706', '81297', '89638', '54794', '94527', '45262', '97932', '78685', '6947', '22818', '48700', '9153', '12289', '22011', '58825', '93854', '65438', '4509', '33741', '28208', '69061', '48578', '40247', '77725', '31837', '39003', '69363', '78113', '76398', '97262', '67795', + '68446', '58896', '60969', '19849', '6722', '91854', '49519', '13949', '67109', '48824', '31723', '75554', '69575', '94986', '75350', '18628', '15284', '41943', '15433', '52607', '41', '22340', '29528', '24059', '34145', '72517', '46316', '10667', '54510', '19882', '47764', '69124', '41963', '84350', '48420', '4646', '24958', '69020', '97121', '26178', '62664', '50622', '32554', '49655', '45398', '11267', '72222', '73363', '89554', '89046', '57384', '29259', '37888', '24850', '74353', '57343', '34762', '2900', '11393', '42154', '94306', '70552', '75265', '921', '26003', '64352', '89857', '83171', '58249', '48940', '53512', '66335', '44865', '68729', '19299', '58003', '39854', '99122', '3860', '80173', '52242', '90966', '53183', '71982', '82325', '87842', '15000', '55627', '71132', '6354', '42402', '91719', '91644', '94533', '74925', '66278', '66911', '85576', '40495', '70919', '71797', '87835', '29845', '71832', '3390', '7994', '33499', '70715', '54897', '82710', '63077', '78105', '24758', '89585', '84607', '46477', '78618', '10989', '39222', '98749', '51685', '94664', '31008', '32823', '89521', '72160', '26952', '4001', '21421', '5737', '74027', '88179', '45553', '83743', '19913', '49435', '65616', '82641', '5149', '76959', '40681', '73023', '2670', '30845', '18863', '35094', '88400', '80963', '9154', '16571', '64192', '59694', '41317', '59942', '58856', '99281', '67260', '66971', '22716', '76089', '58047', '67071', '53707', '462', '52518', '72277', '10681', '69', '98855', '12593', '88842', '67242', '73543', '37439', '18413', '67211', '93495', '45576', '70614', '27988', '53210', '18618', '21318', '68059', '25518', '55917', '56522', '16548', '2404', '93538', '61452', '66358', '3709', '23914', '92426', '81439', '38070', '28988', '29939', '2948', '85720', '45628', '51101', '89431', '86365', '17571', '50987', '83849', '11015', '83812', '66187', '26362', '66786', '22024', '93866', '36161', '90080', '64874', '37294', '83860', '73821', '80279', '36766', '73117', '44620', '84556', '42070', '90383', '27862', '20665', '67576', '34997', '57958', '80638', '84351', '63961', '1362', '14338', '80377', '24192', '41294', '57368', '51189', '27287', '45764', '86289', '65600', '708', '84090', '96005', '55676', '84855', '72385', '70018', '9336', '82701', '3710', '52083', '74045', '96454', '30956', '67369', '78941', '81810', '71906', '23194', '33042', '50794', '61256', '24449', '48639', '22916', '78303', '13666', '40762', '43942', '51075', '89783', '95786', '90462', '6181', '36482', '40675', '4970', '6388', '91849', '72579', '94983', '86084', '20140', '68427', '48123', '43122', '98066', '37560', '6927', '72803', '5546', '62259', '98439', '6457', '98568', '70499', '33022', '28226', '29675', '20917', '75365', '20900', '8190', '56736', '99153', '77779', '49333', '50293', '97650', '4067', '47278', '42761', '71875', '13966', '11223', '46783', '18059', '61355', '29638', '75681', '24466', '89634', '20759', '83252', '37780', '15931', '74893', '6703', '64524', '80656', '85990', '78427', '18411', '20696', '86432', '93176', '69889', '15072', '15180', '9935', '10467', '60248', '42430', '62590', '89596', '27743', '26398', '79912', '60048', '50943', '38870', '69383', '72261', '98059', '55242', '74905', '5667', '54321', '70415', '39903', '49711', '85318', '79979', '59262', '82321', '15263', '17416', '74554', '94733', '72112', '49872', '54849', '73883', '78250', '74935', '68559', '57564', '50541', '45730', '41595', '5588', '83723', '42891', '11898', '14348', '99732', '14481', '85233', '21277', '94508', '52551', '74187', '7634', '42912', '25100', '43536', '35798', '48190', '86477', '22680', '48148', '59501', '56563', '16802', '81496', '97568', '68657', '51462', '67953', '99660', '39002', '54170', '57190', '68086', '52700', '6487', '55709', '70418', '62629', '70420', '35695', '36152', '45360', '53503', '46623', '76000', '50648', '97876', '44815', '29163', '1356', '64123', '71388', '17658', '99084', '58727', '59437', '38773', '71254', '81286', '97545', '18786', '56834', '20346', '36401', '62316', '58082', '67959', '99876', '69895', '80099', '62747', '20517', '99777', '6472', '49189', '31321', '39992', '68073', '13378', '51806', '21776', '52060', '96983', '25754', '93709', '96627', '8644', '93726', '14002', '37716', '87620', '34507', '76339', '24491', '5849', '44110', '522', '66521', '12776', '44887', '80535', '14548', '75248', '671', '73071', '35715', '59474', '7061', '82243', '56170', '20179', '59717', '1725', '24634', '11270', '77023', '63840', '46608', '44667', '22422', '59771', '94768', '73033', '82905', '16463', '40971', '22204', '58366', '28721', '14907', '76468', '81872', '38418', '36989', '61439', '10610', '131', '44296', '35453', '10117', '75856', '94603', '99602', '68075', '35949', '13599', '50030', '69633', '55956', '85465', '16429', '86081', '11145', '6195', '82207', '90598', '92814', '23725', '83204', '80346', '71542', '46634', '15820', '54123', '45397', '15322', '61743', '9273', '71347', '6835', '64006', '91718', '43677', '32923', '21486', '17098', '61694', '43347', '40019', '4071', '52443', '42386', '56839', '83514', '27633', '40780', '51749', '92101', '62384', '92206', '56044', '66174', '11137', '73966', '78471', '30468', '31643', '33197', '6888', '8066', '86603', '74383', '6098', '54411', '98819', '89862', '88639', '94422', '89371', '80526', '91747', '91220', '64944', '76658', '42046', '58518', '27249', '6646', '3028', '1346', '33763', '9734', '31737', '65527', '5892', '60813', '3410', '35464', '43009', '98382', '70580', '93898', '56404', '32995', '62771', '71556', '40538', '55612', '45656', '10758', '20268', '33603', '38310', '14242', '74397', '10722', '71575', '22590', '49043', '91439', '9055', '23668', '9101', '5268', '64133', '77501', '64684', '11337', '47575', '50732', '88680', '93730', '46785', '17589', '3520', '57595', '71241', '34994', '8753', '36147', '88844', '41914', '11250', '94632', '71927', '4624', '86279', '7664', '2659', '94853', '65386', '30438', '86005', '92883', '84629', '59910', '44484', '1306', '8404', '56962', '29990', '38445', '96191', '73013', '66590', '40951', '24712', '18825', '37268', '87843', '18972', '12154', '7779', '52149', '76152', '65799', '86011', '35475', '78083', '88232', '91551', '65532', '93516', '73827', '24227', '44687', '55759', '83819', '45088', '10856', '60488', '39051', '14103', '76650', '81181', '46731', '737', '58788', '78945', '42096', '66731', '66740', '72273', '88969', '5655', '86590', '41096', '80038', '32430', '51877', '23970', '91900', '13082', '45880', '94367', '19739', '61998', '71665', '16083', '57035', '26916', '10166', '18834', '46798', '66881', '28444', '68840', '10459', '81087', '4728', '76224', '39257', '23470', '93524', '37345', '30074', '49856', '22022', '55279', '5159', '5193', '58030', '57539', '12514', '49759', '96222', '52597', '67192', '88187', '53614', '16084', '79915', '28212', '79334', '85283', '32306', '31058', '43113', '74707', '74869', '2213', '32134', '6379', '85426', '87098', '35984', '51105', '69287', '16803', '83337', '14913', '62531', '58098', '7914', '20105', '28850', '1384', '43173', '62983', '87113', '76066', '86320', '77684', '45191', '95225', '41503', '36713', '48404', '91228', '53865', '98981', '59161', '61237', '84561', '17455', '14379', '57789', '80895', '99260', '84595', '72942', '53220', '84448', '81332', '49437', '83086', '93414', '54519', '52288', '74772', '22460', '49324', '11168', '96071', '61985', '38284', '6405', '54698', '71727', '60093', '37340', '87884', '83403', '4542', '94949', '19636', '15855', '39105', '10424', '67418', '91022', '69254', '8481', '38411', '3832', '44354', '93548', '57172', '28481', '372', '81497', '52179', '41060', '72141', '41396', '65590', '70432', '82819', '93814', '26118', '84780', '88485', '70821', '8222', '83000', '47067', '38516', '33347', '47681', '48202', '60749', '52112', '7937', '28105', '11394', '45746', '43252', '34494', '2979', '69715', '42486', '82315', '71760', '97413', '66137', '94487', '7429', '74434', '22964', '55251', '3448', '53534', '2574', '9693', '96157', '2955', '4348', '19566', '56930', '83319', '31310', '53905', '1148', '41726', '22233', '76045', '37351', '10545', '17581', '28047', '30199', '4741', '58111', '33497', '67796', '67730', '31247', '43772', '29461', '45970', '73353', '22534', '53962', '32147', '71392', '62579', '66345', '58246', '33442', '9581', '29705', '14058', '86471', '76125', '59363', '94982', '74810', '89149', '20066', '3366', '3568', '25752', '80036', '64119', '27270', '40061', '91052', '69022', '9852', '77112', '83075', '43924', '61661', '56133', '96652', '57944', '72576', '82170', '79236', '55745', '15309', '88878', '72761', '37647', '67465', '12777', '97309', '93202', '41470', '8787', '64920', '48514', '18917', '35157', '59151', '4640', '5317', '38134', '76548', '82788', '9214', '58418', '73185', '90554', '10543', '47182', '62936', '91765', '89751', '68931', '48865', '64607', '7150', '77862', '14297', '14828', '33013', '91698', '67593', '98096', '16595', '51639', '86531', '24719', '1703', '78788', '43810', '38918', '95491', '99903', '82671', '8291', '68288', '31224', '39863', '4265', '77798', '7698', '33804', '92286', '4744', '37038', '44203', '98212', '17369', '77442', '62879', '4145', '96881', '15646', '36824', '19959', '45451', '76049', '54272', '97577', '95298', '81115', '30204', '82041', '8037', '10052', '8756', '76833', '82851', '24276', '75574', '36037', '78079', '92807', '29064', '90000', '84150', '17102', '75092', '49424', '35597', '4693', '82853', '42511', '16119', '23478', '65240', '55585', '91762', '71671', '46682', '72479', '97696', '24615', '12579', '30274', '48255', '2336', '90202', '5808', '45426', '76308', '74639', '31245', '99894', '89638', '6233', '33893', '71899', '85273', '89429', '29761', '50231', '57249', '99347', '22642', '66972', '86221', '47514', '88274', '10819', '73150', '53754', '13304', '20478', '38099', '619', '14669', '8011', '97657', '26569', '65430', '13467', '38180', '23675', '72350', '42257', '39875', '23529', '53407', '11833', + '29599', '95621', '7727', '59527', '86846', '22860', '5358', '3730', '87555', '362', '95755', '54565', '29935', '68950', '52349', '98344', '86576', '7420', '12236', '15844', '48099', '97535', '97081', '50261', '31187', '60496', '24123', '24042', '6376', '6679', '99806', '20306', '60676', '36881', '77309', '5247', '96569', '53417', '73252', '64179', '35318', '75732', '65119', '32621', '40464', '22887', '96152', '65161', '83381', '8915', '68142', '7328', '85031', '15688', '72519', '93992', '86927', '75538', '38205', '50877', '70039', '97538', '94822', '52131', '49643', '85206', '1347', '14574', '88736', '53442', '49991', '64925', '72283', '82213', '60905', '36118', '62963', '16983', '79185', '15111', '26059', '17792', '98218', '33214', '1094', '41754', '77275', '65173', '13190', '91004', '90422', '44387', '92672', '98641', '54609', '83295', '37395', '70104', '32986', '72524', '82478', '5837', '83916', '52736', '57112', '55985', '42642', '42136', '89642', '35712', '49489', '19726', '65824', '24384', '48112', '15366', '99206', '68384', '51389', '529', '21475', '75749', '95182', '60110', '70571', '74174', '38105', '78107', '4101', '8982', '11215', '23987', '3303', '28706', '54629', '98000', '67510', '30036', '99140', '48896', '40971', '7735', '79984', '50134', '94928', '57023', '52880', '83067', '41940', '62994', '89213', '38593', '19283', '68206', '22234', '19245', '26266', '32403', '65889', '17022', '64280', '42797', '27161', '57675', '42313', '93606', '93082', '20659', '90824', '1226', '66266', '12503', '57104', '15247', '51160', '92398', '71967', '59476', '44465', '35765', '10787', '47737', '45792', '2292', '47599', '89612', '8162', '87622', '69410', '45727', '31158', '99791', '89544', '27214', '99588', '40516', '75616', '36505', '46079', '95448', '97999', '47462', '47799', '82729', '34038', '60789', '96938', '22682', '79062', '93307', '36038', '49016', '90983', '48219', '50889', '32517', '72219', '71229', '82643', '1195', '70543', '17', '22178', '23544', '72371', '1163', '28527', '7336', '39846', '31956', '80963', '41804', '59791', '41831', '1940', '52377', '79494', '12531', '81112', '44320', '18746', '5774', '63869', '4085', '59922', '12751', '99443', '13530', '23872', '36026', '83360', '32711', '92980', '11140', '99323', '57263', '98149', '29265', '25548', '65995', '4818', '15593', '8535', '37863', '12217', '14474', '66584', '89272', '86690', '58777', '39666', '44756', '18442', '52586', '98030', '40850', '38708', '49304', '68923', '65008', '84388', '83639', '29866', '63675', '26793', '49227', '82099', '24090', '57535', '24201', '65776', '74054', '89833', '62979', '26613', '5851', '99766', '63484', '66605', '37179', '90760', '59336', '58390', '93239', '84578', '11396', '93994', '73818', '23972', '37720', '72369', '25063', '32952', '71036', '76612', '31285', '34090', '19136', '53783', '66436', '61478', '96749', '43658', '7399', '31574', '67073', '40480', '20727', '70993', '65549', '30800', '21507', '53785', '89574', '86381', '56492', '62603', '44856', '68687', '63794', '70996', '7475', '84238', '71939', '86886', '94792', '15036', '36936', '95722', '17771', '67850', '33371', '49314', '40744', '5432', '81057', '41201', '75986', '22961', '15323', '1570', '18657', '95219', '19130', '53127', '15867', '81135', '73206', '76668', '36386', '48828', '31417', '56916', '70891', '60534', '95777', '10022', '94053', '2928', '56326', '16559', '79656', '6414', '81247', '78270', '55687', '19151', '61597', '99857', '81142', '27725', '53493', '12185', '1455', '48501', '59425', '20591', '24900', '66079', '84889', '32024', '18919', '2043', '7076', '71201', '88258', '86521', '93348', '26395', '39646', '44145', '33911', '46231', '67054', '39979', '11630', '23020', '76278', '88056', '11480', '4723', '78612', '70211', '60622', '84687', '59092', '65675', '38479', '64399', '64699', '95964', '42764', '69060', '28189', '4193', '95805', '75462', '17245', '59640', '94773', '84292', '53092', '98507', '61353', '32483', '53027', '48912', '87221', '47788', '59263', '65196', '35567', '17494', '64253', '50223', '7057', '87467', '62414', '2523', '50910', '72353', '78986', '78104', '47719', '29108', '12957', '5114', '64435', '66707', '37449', '70399', '45334', '71606', '55338', '55072', '58765', '12151', '22012', '16954', '87366', '14240', '98041', '72296', '47408', '56879', '99584', '63172', '92316', '28071', '29880', '19608', '13839', '87484', '56541', '88662', '87098', '72124', '78282', '27653', '38993', '31870', '67239', '99445', '7376', '78487', '98880', '12180', '86773', '67773', '15416', '58172', '13075', '67559', '97510', '29705', '86985', '57024', '11827', '31236', '91920', '26116', '94614', '14486', '46252', '78847', '43786', '70048', '96739', '35240', '39933', '58209', '27852', '65669', '47323', '58150', '84444', '44344', '95882', '41258', '31314', '69060', '19916', '6979', '19436', '45572', '16259', '74566', '6306', '24705', '53422', '593', '97031', '22308', '26875', '23042', '78035', '34229', '61976', '23175', '50072', '90896', '50810', '71730', '86468', '94807', '8218', '36032', '58628', '60560', '51206', '37943', '27987', '15014', '49905', '70018', '66799', '80851', '23594', '29982', '6438', '97381', '47715', '96294', '17985', '48545', '12672', '5250', '9988', '24601', '3736', '97815', '54363', '64703', '44167', '68376', '16595', '38073', '29630', '59630', '1858', '71823', '75580', '70083', '14493', '93821', '93394', '85369', '3818', '8435', '59988', '43966', '13961', '15855', '83332', '80312', '27299', '88840', '76964', '56173', '62794', '79389', '82642', '85843', '47116', '43064', '16061', '28905', '54415', '72832', '91252', '93488', '79457', '99336', '70744', '80432', '6487', '880', '87701', '154', '86574', '86677', '17892', '81488', '95260', '12515', '43189', '9211', '55403', '41417', '60046', '54785', '83655', '28274', '65745', '63062', '44549', '36391', '48051', '7328', '3572', '33226', '49177', '25123', '59065', '19691', '15109', '10172', '95578', '29497', '48152', '20276', '36270', '78866', '48309', '53209', '55475', '30073', '19717', '16004', '45692', '83430', '9291', '45935', '57030', '92613', '91656', '67697', '34915', '28156', '56594', '3273', '11194', '98270', '34370', '2621', '66679', '97451', '97717', '87923', '48310', '37725', '69743', '75103', '84956', '75163', '16069', '65304', '19397', '18071', '27273', '49823', '57595', '98324', '82174', '10293', '80943', '64184', '19472', '4198', '9410', '25927', '65961', '33155', '95168', '33692', '61712', '69877', '13308', '17415', '10022', '2491', '67310', '96140', '68050', '76272', '17143', '76805', '57176', '7539', '22690', '95483', '87592', '27221', '90821', '51154', '99828', '68998', '54581', '74222', '10269', '65057', '45467', '96089', '55058', '89779', '60837', '74122', '52886', '58055', '14880', '93208', '66652', '68830', '24121', '62407', '87257', '18802', '14925', '45423', '98624', '55195', '59072', '41414', '77840', '66075', '62705', '26549', '19063', '57552', '2507', '52069', '57620', '66688', '14833', '33700', '90666', '98052', '5367', '2268', '43093', '69063', '22030', '85564', '92258', '1847', '24446', '65835', '38660', '91899', '87732', '52396', '31952', '36000', '86944', '16109', '80729', '53757', '60226', '59103', '84187', '36674', '72823', '29884', '4654', '69139', '20440', '57413', '3651', '39639', '44564', '57492', '84159', '751', '99748', '9659', '72661', '39220', '99742', '74734', '75729', '38071', '69934', '73640', '65294', '54524', '64372', '37927', '17187', '7863', '12732', '40296', '36197', '15821', '76831', '4400', '71933', '4040', '22072', '33064', '25702', '13324', '91275', '27388', '97729', '14620', '45989', '80737', '17934', '4219', '3032', '43457', '31051', '24469', '67041', '29328', '75499', '80951', '88212', '92595', '49969', '24612', '58732', '2718', '3805', '50918', '99426', '8614', '35580', '93273', '989', '24385', '41185', '25687', '47146', '25227', '95839', '56355', '98536', '79824', '31725', '46447', '26690', '68418', '47783', '33725', '21729', '70797', '59038', '60376', '25087', '68332', '67950', '12411', '95918', '64736', '65336', '74947', '64605', '4106', '42712', '96640', '28492', '28648', '42429', '821', '24333', '69677', '38959', '23484', '92005', '29352', '29159', '52873', '99947', '21834', '85347', '93479', '28298', '55608', '3226', '69714', '80283', '6577', '18849', '44605', '75286', '28139', '26541', '12867', '57500', '86617', '33005', '57498', '60223', '74954', '51401', '55246', '5648', '16513', '40930', '43821', '32090', '66002', '65530', '76083', '6047', '6879', '94987', '80787', '11688', '77161', '92670', '6696', '400', '28572', '47234', '51375', '88518', '762', '92617', '54260', '7560', '60180', '43331', '64059', '27616', '75839', '21392', '47756', '46254', '19486', '88533', '30130', '93694', '8557', '66534', '94447', '16910', '6480', '77440', '24366', '6195', '48946', '28597', '44429', '50300', '73556', '40638', '98709', '94413', '15987', '43860', '64871', '93953', '34506', '7296', '31753', '30626', '77510', '39829', '25696', '39776', '69185', '36540', '65413', '31528', '43446', '73532', '49776', '30282', '30004', '26725', '15200', '33958', '90320', '71836', '48051', '31970', '5326', '96194', '69695', '60898', '60945', '18271', '50868', '61468', '23593', '68985', '20628', '58044', '8942', '34849', '7384', '50500', '62895', '78780', '48946', '65278', '4067', '973', '34761', '15512', '73739', '23138', '47322', '55568', '32259', '71816', '49277', '75218', '76104', '19579', '68312', '67904', '33886', '53888', '26421', '43859', '40291', '39068', '31711', '36542', '10195', '39781', '72352', '13188', '34113', '9428', '60443', '4987', '13783', '80744', '63483', '18266', '11961', '87167', '46987', '28480', '74214', '39191', '8146', '38090', '75727', '79245', '47720', '52547', '45321', '4972', '49701', '74354', '69672', '63455', '41902', '5667', '54166', '4962', '25873', '44509', '73332', '73383', '29438', '21455', '12320', '11997', '16921', '49379', '63027', '86175', '8110', '76149', '2520', '11256', '25863', '50518', '69001', + '79113', '9447', '91840', '5242', '10998', '46496', '2448', '56058', '20970', '10517', '17783', '25723', '97137', '62840', '1264', '78691', '81020', '55335', '48524', '2088', '90413', '76651', '26855', '16177', '14954', '62914', '21344', '5708', '75560', '39311', '95865', '28783', '64902', '95657', '46276', '33426', '4799', '11588', '57513', '73689', '77677', '63011', '97795', '34954', '76866', '32043', '32697', '26643', '36890', '53476', '3011', '13963', '49551', '87671', '67761', '17488', '94770', '50599', '33272', '23091', '38079', '41177', '22395', '91656', '79679', '38687', '57384', '80118', '42507', '4098', '78949', '45669', '48802', '83915', '78292', '4369', '57657', '49146', '45192', '98491', '72457', '46331', '207', '81601', '7409', '70856', '91605', '70295', '9171', '72293', '32997', '78025', '16795', '73534', '68780', '21284', '31767', '94381', '86439', '12420', '53285', '99563', '60502', '67954', '55012', '99809', '5431', '69978', '99712', '14401', '79498', '4495', '3045', '528', '72542', '91604', '72725', '39378', '80378', '41996', '20138', '54545', '59730', '36951', '45157', '37964', '97690', '12184', '4944', '53803', '93605', '60851', '68938', '46285', '89663', '90309', '6907', '87239', '81791', '83292', '90013', '68927', '14725', '81840', '63836', '52068', '43830', '4794', '931', '59255', '8263', '99057', '94401', '69033', '7437', '20364', '92884', '28193', '43932', '37629', '59426', '18891', '8583', '79551', '87242', '1483', '6725', '65786', '16844', '12650', '99305', '42841', '9811', '18800', '39313', '51373', '31874', '84558', '27831', '48614', '48975', '55509', '83363', '31854', '64001', '94028', '76125', '79314', '24893', '81132', '9441', '86015', '28356', '40358', '10160', '23328', '7330', '76538', '37611', '89351', '84132', '97047', '26109', '95222', '35130', '75600', '88602', '15073', '87835', '71649', '28948', '81615', '37498', '28674', '59776', '44095', '65924', '64368', '94536', '12518', '61711', '55619', '82949', '4114', '21540', '70544', '28022', '79983', '28781', '7749', '97873', '4951', '50076', '47611', '99522', '56820', '38653', '49047', '36283', '83908', '72452', '85625', '10811', '36998', '44083', '34864', '44975', '39057', '4551', '68450', '24781', '1503', '9871', '46885', '11424', '21259', '54900', '97669', '85669', '6015', '2521', '37661', '14915', '57423', '91903', '94789', '32059', '64972', '4600', '61465', '27118', '79785', '13547', '49766', '38410', '68860', '63756', '23621', '64387', '46255', '63408', '11297', '41081', '56326', '58349', '98703', '72268', '73574', '32098', '42534', '91502', '38083', '11241', '56828', '12098', '25377', '37054', '56328', '30034', '26922', '68401', '93478', '63275', '62650', '81407', '773', '79499', '14970', '47217', '1187', '57428', '69980', '77764', '74791', '22107', '54363', '39247', '56028', '56982', '84244', '21464', '18716', '25533', '94589', '94768', '21537', '18436', '81135', '27654', '79713', '56630', '61571', '58453', '26758', '68450', '68449', '2994', '15347', '83954', '71823', '6428', '44210', '79597', '95144', '32871', '1991', '320', '77157', '63607', '31154', '48846', '71125', '61750', '59608', '33038', '35733', '68915', '94127', '50383', '64242', '49708', '57270', '65019', '8581', '12111', '18487', '50013', '58664', '22214', '19033', '33681', '44754', '28830', '10381', '52318', '34959', '20682', '55453', '53800', '65774', '99164', '72102', '36986', '44157', '56716', '7974', '81475', '25926', '39402', '33688', '99671', '95312', '42268', '26536', '14482', '67377', '57993', '89147', '15834', '64995', '4700', '18714', '30221', '39095', '32749', '69257', '55204', '30497', '31839', '63045', '30009', '62683', '31232', '77680', '93551', '63589', '6989', '77246', '42169', '46117', '73226', '37427', '1858', '83649', '37410', '86369', '4641', '74481', '66168', '48041', '22597', '14670', '27464', '57165', '20939', '36282', '76940', '73358', '50521', '69603', '8895', '81793', '57743', '81903', '64025', '91641', '25276', '34040', '62642', '64015', '57657', '84890', '73832', '782', '60160', '16998', '40023', '24590', '88613', '76640', '53091', '67600', '80183', '45674', '64464', '25163', '42384', '66972', '13953', '41966', '66048', '15135', '73745', '19466', '53657', '34619', '13462', '15905', '48257', '73297', '238', '93525', '80556', '5942', '5411', '66169', '9090', '95130', '74316', '57321', '48083', '62355', '68113', '15239', '36644', '80326', '65817', '54428', '61955', '58849', '77206', '16073', '98261', '92091', '39178', '35464', '85109', '85452', '21128', '25665', '81860', '44664', '24024', '56960', '95124', '39786', '18836', '11121', '44163', '81074', '79064', '46219', '94694', '44233', '81469', '24642', '15030', '21995', '13587', '40755', '6669', '81093', '74305', '1881', '55649', '37273', '80827', '98643', '46694', '59281', '79231', '42813', '84984', '7052', '98113', '17296', '84434', '31205', '46894', '71219', '74530', '44686', '70744', '91388', '20692', '96853', '73803', '15836', '18126', '49686', '4179', '47588', '87892', '65425', '68012', '97468', '92510', '99271', '58694', '11918', '37051', '18644', '57228', '14265', '57572', '57022', '52186', '30193', '93570', '87872', '5257', '26784', '6476', '61746', '68559', '1720', '26202', '16519', '27688', '10645', '87174', '60845', '73385', '82075', '6933', '98828', '56895', '17344', '84253', '36561', '51648', '24939', '63470', '31034', '95052', '51090', '51465', '87979', '68650', '30181', '29598', '19137', '43221', '81353', '90170', '96985', '61115', '17385', '92314', '80650', '55821', '17874', '84333', '93272', '48260', '87272', '22764', '59957', '51870', '85988', '39222', '77241', '62535', '28344', '6011', '80831', '64551', '46299', '75195', '71177', '8660', '58943', '57003', '3306', '74413', '74068', '15073', '89016', '93140', '13911', '57170', '19880', '41870', '9131', '57495', '73032', '86979', '60094', '87026', '30880', '4736', '86301', '92707', '21689', '83565', '71275', '47665', '65687', '71184', '89897', '32490', '97577', '38723', '79113', '37531', '97500', '94450', '15699', '58019', '84423', '27057', '56017', '97148', '47365', '30669', '33818', '80406', '99690', '33012', '95178', '46809', '48448', '79350', '9146', '99701', '98976', '71197', '44161', '75069', '36602', '79650', '97301', '12020', '56658', '25701', '46392', '78609', '63073', '69419', '57736', '20102', '42415', '79044', '20277', '56280', '47903', '94311', '25558', '40336', '91305', '90505', '66769', '64562', '83737', '62892', '10375', '71024', '19988', '56946', '76110', '21847', '43162', '50578', '46086', '54167', '61722', '53463', '63134', '69288', '12838', '14116', '71687', '50846', '59810', '24826', '84138', '82885', '91496', '98600', '82769', '40049', '4125', '50694', '1294', '2805', '29691', '82321', '76462', '85945', '115', '29188', '66918', '71340', '31585', '61638', '95472', '52978', '50622', '81990', '60955', '70519', '22270', '35610', '95871', '89222', '41038', '52546', '1163', '67943', '1793', '92010', '35755', '74509', '66665', '95759', '8568', '44299', '67822', '5806', '85839', '13895', '87675', '31357', '88014', '40026', '53050', '28951', '31992', '42495', '82892', '51567', '2869', '45808', '20238', '20781', '56098', '66307', '95701', '614', '60833', '3091', '81339', '24195', '65639', '85976', '28116', '66224', '51502', '73637', '13207', '88302', '36488', '65518', '98187', '26', '74367', '64706', '53943', '86760', '25783', '82112', '34958', '86621', '20848', '63459', '14049', '84943', '91873', '50238', '77773', '64109', '8602', '87934', '47583', '66053', '30287', '5507', '80312', '37464', '57457', '86200', '17806', '16522', '38843', '94334', '59958', '63864', '53427', '74506', '33980', '90449', '30842', '53616', '36738', '52', '13595', '53051', '13174', '60163', '71420', '73835', '67119', '79018', '42782', '45059', '952', '46360', '85879', '71552', '84741', '29746', '32577', '10041', '7208', '97528', '51256', '916', '55973', '17684', '99046', '38782', '58660', '97798', '66032', '48339', '51329', '12532', '97904', '95454', '42737', '62541', '96702', '82953', '94610', '26645', '86813', '25480', '99713', '26078', '23028', '93056', '21445', '73209', '89318', '69987', '34705', '30064', '17094', '51135', '54141', '26625', '1086', '13082', '30843', '98672', '56864', '42605', '5833', '60850', '69366', '27351', '16456', '92609', '48030', '54322', '69891', '46502', '34578', '77918', '63276', '75958', '42519', '60266', '85576', '4855', '14258', '67017', '10545', '35078', '53012', '71922', '85784', '73402', '74363', '58457', '94102', '23510', '51559', '39482', '87057', '9377', '10106', '82985', '33931', '16523', '6484', '97749', '83172', '53753', '27466', '23073', '96083', '67302', '57465', '21877', '18013', '99804', '32873', '43123', '72365', '53197', '80578', '69770', '97471', '86954', '67183', '98497', '78474', '28450', '63183', '98699', '42738', '61433', '3491', '27304', '49311', '94980', '92740', '43272', '86549', '11406', '79636', '85582', '38086', '657', '2354', '26567', '77450', '42086', '21600', '49011', '44059', '47872', '75761', '96577', '11642', '83471', '79616', '23749', '77082', '96876', '65302', '84027', '48955', '59887', '20657', '75090', '9058', '50347', '66088', '70745', '76342', '58026', '95568', '61504', '93473', '84590', '47089', '74717', '93090', '46334', '68273', '59500', '54345', '72608', '54048', '86156', '40296', '74046', '6813', '36369', '74543', '18305', '85236', '31316', '37061', '96893', '23112', '5529', '10166', '19037', '1467', '70810', '30932', '18410', '92837', '81324', '12268', '54705', '25207', '90366', '56528', '3392', '88747', '39951', '97957', '99404', '23685', '13533', '15640', '11434', '66516', '71025', '65770', '88000', '52232', '32360', '10787', '37438', '2264', '94460', '80214', '42288', '59062', '29010', '64093', '21225', '22297', '36935', '19202', '5925', '85373', '27414', '28991', '9191', '42273', '56587', '89719', '77191', '64334', '61542', '28763', '28978', '79184', '59815', '95200', '30246', '54022', '287', '91808', '66347', '50833', '15356', '78614', + '65087', '9664', '67555', '58222', '20787', '72382', '83712', '15858', '72040', '59451', '7428', '47586', '83509', '45969', '28759', '94033', '88618', '46', '1753', '28290', '71934', '99070', '52517', '65865', '15904', '68134', '87595', '39779', '99174', '13366', '50847', '69037', '77911', '19709', '84404', '24370', '18920', '1746', '28059', '4653', '6892', '25496', '48810', '82943', '7069', '44018', '1617', '56497', '27582', '29576', '47883', '8385', '54975', '96245', '77257', '31194', '34512', '19198', '50926', '50886', '91577', '49260', '49604', '58464', '18198', '90887', '15379', '74883', '36644', '63967', '34545', '20539', '12884', '6010', '98636', '94832', '47702', '98318', '6078', '42517', '97030', '93707', '39286', '10245', '66230', '99574', '74563', '81937', '22153', '10659', '67579', '85147', '69686', '32017', '8199', '20027', '64266', '60707', '55426', '22027', '13823', '81404', '86757', '3754', '197', '45469', '68736', '17656', '92453', '6784', '35531', '33538', '27558', '35825', '13471', '16377', '66978', '44601', '69943', '84635', '7335', '67725', '88064', '78201', '64380', '66771', '62221', '60427', '32028', '37857', '5491', '2757', '10537', '2199', '60244', '14726', '29734', '34433', '81241', '39778', '65831', '56153', '81696', '25113', '17371', '79022', '3587', '60439', '96582', '37801', '82496', '68242', '19561', '53140', '17171', '13165', '58750', '80612', '19818', '16753', '70009', '75290', '48846', '89851', '25190', '35525', '84348', '65298', '23161', '60583', '89611', '18798', '85422', '60713', '17660', '41915', '65757', '4781', '48374', '10712', '40330', '2409', '41020', '28042', '51857', '81224', '93917', '90366', '58848', '8012', '92070', '75349', '80066', '83228', '55170', '78376', '94127', '29418', '58660', '74006', '63909', '59502', '63255', '32318', '28904', '26117', '88103', '50656', '58517', '16372', '43392', '77876', '65997', '63501', '45927', '17444', '84021', '54886', '57082', '47456', '73816', '66900', '82958', '49722', '95843', '23458', '4560', '67276', '59080', '81486', '2967', '26133', '87694', '74183', '22100', '45306', '33895', '26512', '71426', '54994', '47367', '10171', '45681', '36268', '3166', '2179', '64197', '90037', '4641', '96073', '72989', '55123', '48825', '2862', '66974', '30115', '41554', '26727', '54025', '69504', '38284', '7816', '36370', '75764', '69774', '43208', '43598', '39461', '21655', '12169', '77790', '44578', '70959', '13500', '40823', '52952', '88095', '82193', '66424', '79814', '25651', '58125', '42724', '11752', '64533', '34827', '72755', '96727', '82066', '60268', '55535', '4230', '73018', '69602', '16912', '66088', '21859', '38654', '38638', '51444', '37999', '18595', '15209', '21801', '21130', '53741', '54954', '91590', '83660', '74071', '82627', '4311', '45268', '94735', '65747', '72428', '22621', '70828', '64394', '647', '23570', '17677', '84377', '63993', '10268', '47426', '72750', '83772', '29090', '73284', '36683', '91143', '64546', '99836', '21999', '61793', '41557', '16714', '20586', '14251', '56633', '46146', '84730', '5445', '8367', '52621', '79252', '89737', '18431', '32134', '86975', '58939', '63385', '8504', '25998', '79549', '70558', '4870', '57604', '48374', '32388', '97871', '75590', '10919', '43825', '82858', '25807', '50366', '2841', '2716', '51315', '79719', '33159', '63382', '11327', '65184', '87243', '17850', '40149', '12171', '48486', '26380', '85432', '35427', '59256', '57601', '29529', '20553', '3006', '69997', '87919', '47626', '96026', '37445', '51735', '89296', '26702', '22837', '61279', '85193', '30624', '10676', '83075', '21477', '54708', '47485', '80297', '86204', '25192', '55197', '81177', '70551', '11003', '7001', '55017', '487', '40926', '99463', '79514', '69697', '52854', '88640', '44464', '66314', '48240', '49787', '81333', '14914', '12919', '51037', '88609', '25572', '61019', '85184', '12051', '61246', '52108', '98895', '24549', '86944', '73303', '9012', '25151', '97424', '43531', '44790', '63034', '86713', '76483', '17499', '86891', '3267', '45091', '39126', '94419', '35750', '35239', '49413', '62381', '92010', '7246', '26997', '47446', '26930', '22668', '43961', '51741', '63058', '41977', '62933', '9197', '94303', '29044', '53755', '22391', '85373', '66572', '74650', '7824', '49712', '40021', '99958', '60404', '37370', '89264', '52343', '90901', '44730', '4252', '5811', '22283', '25102', '86636', '75509', '47088', '62971', '85519', '7495', '16798', '25708', '59258', '89361', '43455', '86768', '29961', '4362', '60956', '81059', '87604', '46241', '98362', '21030', '76182', '83545', '59150', '99333', '68271', '32629', '3364', '96467', '40427', '307', '84267', '239', '11711', '40933', '24518', '33854', '60291', '94179', '5564', '33196', '73818', '22201', '97078', '69360', '94513', '42623', '6510', '67378', '79468', '10394', '96430', '87701', '2667', '64162', '93266', '48941', '55345', '56127', '22704', '8793', '57008', '36920', '80845', '81203', '98715', '84158', '49194', '72718', '52919', '4951', '8715', '82384', '8570', '26733', '62399', '27297', '79038', '57916', '46155', '82381', '1027', '20541', '40580', '44836', '17336', '55548', '87454', '63549', '61401', '88819', '23326', '37546', '49089', '50707', '23099', '20724', '67184', '3394', '95941', '76045', '20523', '30393', '14157', '69381', '94104', '15406', '46707', '36234', '9136', '96805', '4904', '20310', '77164', '15400', '87198', '48310', '59729', '35230', '61503', '42015', '86910', '23264', '23542', '49105', '58334', '52855', '78865', '73516', '43820', '96593', '33168', '26170', '88241', '4016', '79862', '39617', '95329', '57881', '71750', '89690', '22519', '59367', '19825', '12638', '36100', '14355', '79540', '8411', '94571', '80462', '11953', '55629', '14598', '81066', '48968', '74149', '36938', '4564', '59157', '75517', '14309', '64905', '59893', '62803', '6968', '33003', '40894', '48816', '77710', '16692', '19135', '98381', '49397', '24048', '17804', '26829', '24046', '44546', '28174', '2639', '27957', '38625', '85902', '9908', '77666', '14096', '89851', '23600', '20717', '32860', '44070', '67853', '85907', '23761', '789', '73370', '15649', '26472', '9174', '20081', '49415', '97463', '14565', '19834', '94738', '68045', '67542', '3552', '77093', '99071', '16832', '95177', '49571', '85821', '9368', '85170', '58449', '89633', '99302', '94158', '50274', '50223', '51128', '52847', '53598', '47826', '2883', '28192', '84324', '9530', '14385', '37292', '74795', '16821', '5010', '77101', '96596', '72384', '41399', '83046', '37927', '48213', '84574', '55438', '79315', '71005', '45190', '56133', '14016', '92180', '28365', '34307', '90665', '74758', '45080', '38017', '80599', '91174', '47907', '19299', '9707', '92260', '36784', '55855', '25939', '74472', '47402', '12352', '75591', '31459', '76711', '57940', '95535', '55231', '80645', '84613', '90280', '3500', '83695', '42992', '77226', '25326', '8093', '49838', '6457', '44814', '82819', '94986', '81818', '65186', '21378', '49711', '66248', '72391', '65826', '21284', '41399', '72858', '32223', '35915', '45221', '36871', '16193', '2522', '52963', '24506', '98239', '56752', '15192', '8451', '62802', '54777', '67983', '82177', '7303', '71445', '40559', '58655', '73468', '40491', '52864', '81558', '36789', '53134', '38801', '90600', '36385', '90996', '20526', '13627', '62253', '96989', '88864', '11928', '14681', '77082', '95659', '47182', '16085', '26894', '39758', '32803', '26458', '65779', '66110', '38888', '15490', '48120', '90238', '8736', '233', '76851', '86938', '8873', '95387', '33400', '50788', '13568', '43139', '29821', '70427', '21022', '93285', '57243', '51675', '77459', '33170', '81485', '85303', '44133', '203', '44175', '89151', '26705', '32990', '10885', '10208', '58477', '97729', '699', '40581', '8065', '95864', '89797', '47506', '19160', '85728', '58599', '96271', '75849', '30736', '18808', '25828', '52011', '66179', '70244', '81312', '19570', '14287', '61078', '81922', '63361', '80858', '306', '22156', '82923', '53176', '24864', '49193', '2961', '96536', '62449', '13213', '85347', '11442', '76615', '43037', '86122', '99676', '74309', '46017', '16175', '12685', '53550', '19080', '37283', '44921', '34991', '4433', '99561', '38215', '35662', '13892', '7814', '41718', '41231', '85589', '74048', '72169', '26946', '61732', '9135', '39009', '63534', '4114', '40417', '83412', '22562', '65546', '720', '90064', '73027', '50736', '71086', '12445', '3681', '65140', '56291', '47452', '48916', '65136', '53941', '15484', '21038', '47251', '78461', '31031', '4838', '87483', '732', '16111', '68263', '4811', '65979', '44283', '51659', '29997', '11280', '3880', '12399', '63450', '93862', '50981', '62790', '76784', '76696', '40906', '49261', '35863', '43747', '65954', '36125', '73713', '98678', '13409', '38773', '59417', '9763', '429', '66203', '7350', '32754', '36079', '72447', '63925', '12958', '65292', '80270', '78432', '50925', '74946', '7649', '13689', '68001', '52318', '5804', '51584', '63637', '85697', '50929', '25279', '20963', '83038', '31199', '64189', '17152', '20459', '66108', '66005', '53159', '53971', '32528', '77145', '52981', '88941', '68593', '86343', '97770', '25625', '17598', '55249', '89640', '94162', '65874', '36511', '21906', '70401', '30914', '24085', '42945', '55597', '78393', '98120', '38283', '44967', '76077', '45739', '92432', '11846', '59131', '26322', '82651', '94792', '37726', '23301', '11275', '98813', '34229', '65440', '51369', '55580', '35207', '84314', '35696', '50231', '9399', '18679', '27219', '22519', '26725', '63451', '79357', '55915', '77027', '30354', '45890', '10745', '60035', '7914', '43562', '12219', '30220', '29382', '72520', '87475', '83634', '15163', '32468', '72904', '18200', '84666', '43560', '58483', '64613', '52170', '55490', '45954', '99323', '26401', '61210', '10450', '70360', '42906', '32851', '70022', '49966', '62331', '84249', '98093', '62146', '88171', '73246', '48314', '45730', '56348', '59081', '16642', '57872', '81564', '32305', '4158', '47263', + '97234', '74415', '36159', '30014', '22241', '77574', '27990', '67395', '81471', '18512', '47546', '23386', '6156', '72893', '15332', '57667', '92657', '35148', '45316', '90482', '93819', '38065', '74899', '10850', '63285', '50968', '88081', '42486', '56089', '43288', '11239', '55127', '26637', '85974', '93879', '78540', '42451', '35082', '93809', '63793', '51039', '13518', '20239', '26933', '19322', '26648', '83711', '93163', '95951', '77389', '43771', '36873', '66976', '38082', '59476', '53984', '6951', '42615', '80733', '1120', '80595', '10500', '67420', '38885', '8892', '36205', '17170', '46564', '66415', '36372', '68305', '41470', '38699', '60900', '23468', '6927', '498', '55896', '4005', '50692', '67984', '91012', '97314', '94177', '57676', '36734', '32671', '44733', '34981', '52186', '15599', '75642', '82652', '22773', '97106', '20691', '38085', '50368', '74916', '76281', '54002', '85721', '99186', '78438', '27865', '34827', '61315', '8817', '93105', '71539', '35484', '58033', '17540', '32806', '87253', '15780', '80123', '34241', '70383', '95515', '27998', '47682', '32682', '93658', '15116', '93030', '71866', '35516', '70161', '7556', '64122', '54622', '14312', '64375', '28863', '27886', '34040', '10010', '1460', '58765', '71496', '37785', '5616', '84850', '2194', '55514', '33636', '7138', '36937', '44763', '61308', '63574', '8069', '24109', '17821', '82144', '53309', '26183', '84238', '36684', '45285', '41353', '29380', '93726', '59560', '96422', '34218', '66851', '49001', '4855', '46849', '19877', '76540', '61415', '32053', '38801', '74623', '92808', '6660', '85031', '97706', '34417', '51085', '72292', '30903', '45126', '69978', '11572', '68622', '64123', '59344', '67118', '46014', '59248', '69321', '31897', '72232', '48016', '36455', '87125', '85356', '96888', '28316', '23149', '34823', '29944', '18522', '14045', '973', '49472', '89165', '84112', '94087', '47881', '87600', '86330', '13384', '4528', '94572', '30634', '86728', '48525', '53243', '35911', '96382', '22525', '89914', '52213', '23007', '54827', '35721', '49121', '40203', '99040', '55039', '94543', '85440', '75098', '12566', '15579', '40603', '51321', '28805', '46550', '42499', '69794', '51322', '37286', '72035', '15494', '39787', '97639', '24343', '36299', '72759', '96672', '58801', '57467', '97185', '19493', '4431', '33940', '950', '46713', '12503', '35185', '31106', '93821', '1086', '31767', '17484', '52751', '70411', '12196', '502', '45391', '70720', '27507', '1282', '18633', '45031', '10475', '83570', '29539', '16753', '63494', '17010', '76069', '38913', '53948', '34175', '36761', '37575', '73655', '76272', '1069', '74456', '10440', '65502', '95286', '39384', '83461', '76477', '4167', '46503', '22373', '24523', '46024', '28959', '83219', '27807', '80905', '88626', '70234', '86888', '60954', '95397', '47973', '47944', '30154', '42698', '15144', '53223', '21123', '19281', '62933', '24952', '84744', '58456', '38446', '26768', '40797', '107', '52101', '8348', '8531', '17772', '97826', '34009', '15825', '48977', '54939', '78886', '31784', '42842', '22773', '9095', '25113', '65362', '83953', '55921', '92797', '26776', '59312', '56428', '52218', '50141', '52535', '22564', '50708', '50384', '16261', '529', '31406', '46452', '30954', '5385', '60190', '38790', '65440', '11891', '2196', '83560', '68884', '72400', '47795', '7501', '8916', '63267', '35567', '39889', '61818', '94343', '46612', '75029', '46988', '12411', '6123', '60904', '43704', '31143', '72544', '45919', '67953', '97776', '49517', '60476', '54437', '46261', '99778', '18541', '77626', '12537', '68459', '12688', '36284', '54901', '89375', '10538', '38415', '33160', '78777', '33532', '82538', '21329', '34359', '29544', '57035', '61945', '49098', '32484', '68236', '11088', '57533', '11044', '96786', '58861', '51390', '9582', '24229', '32604', '66195', '7311', '46441', '73383', '58033', '41866', '19293', '73085', '50627', '19818', '40498', '56436', '99865', '55516', '38917', '89889', '49571', '99408', '20144', '76122', '49593', '47906', '94763', '26488', '86343', '98334', '70112', '85244', '45622', '47828', '35306', '86838', '57186', '69907', '90594', '68206', '25118', '75445', '71715', '15800', '67558', '17783', '56525', '22970', '17354', '17139', '76827', '50325', '95314', '65432', '44045', '57928', '66247', '10673', '69744', '99485', '57467', '66889', '55246', '15095', '23540', '32890', '22959', '59472', '62237', '6956', '34669', '16547', '54868', '22598', '65120', '48525', '72750', '70559', '75706', '61831', '14032', '36146', '90211', '36082', '79712', '43018', '53903', '82490', '45698', '54202', '83079', '4867', '18044', '55144', '49189', '33278', '48387', '68822', '73057', '58118', '89796', '47318', '98383', '58759', '172', '56627', '79861', '86734', '25758', '80779', '55741', '40924', '24568', '23090', '62934', '94264', '58331', '18747', '15802', '81585', '92542', '97426', '18205', '11820', '62702', '16439', '18613', '45918', '47584', '98743', '39808', '33357', '16033', '87378', '87036', '88920', '99300', '89343', '7384', '36867', '36712', '96947', '92141', '85779', '81735', '86121', '19511', '70519', '62537', '10398', '99308', '63922', '45419', '17708', '2093', '85127', '55753', '97149', '82877', '64642', '30417', '151', '75464', '75992', '99440', '58040', '32083', '90604', '47830', '40087', '78899', '43638', '59066', '46579', '44828', '35130', '10670', '62051', '94127', '32024', '85455', '80408', '18295', '8106', '89380', '90499', '3196', '3826', '63462', '64317', '55570', '77162', '48564', '59842', '80241', '76221', '57327', '48049', '74336', '43168', '19559', '32059', '99226', '46384', '48111', '56013', '58953', '68426', '22', '72641', '16207', '595', '71706', '61213', '65921', '67517', '92618', '57660', '76414', '60998', '1829', '90176', '62932', '15052', '94997', '41', '58848', '56411', '18129', '86542', '16330', '2803', '5651', '47351', '57866', '3560', '97530', '8338', '59434', '50183', '39076', '2516', '16293', '6559', '31189', '83713', '58214', '32016', '56581', '46226', '74599', '33513', '51530', '20163', '56512', '1694', '8165', '17370', '2510', '46015', '80417', '77195', '69062', '717', '33699', '37638', '82238', '5436', '67991', '98554', '26668', '19565', '26500', '30133', '54349', '36668', '56773', '55187', '25458', '54126', '11833', '32007', '38881', '20038', '42186', '67850', '12001', '96089', '63397', '75035', '16744', '45208', '84186', '82044', '34818', '55858', '1623', '41600', '34753', '92242', '16416', '49800', '45309', '56520', '38893', '42865', '37476', '78860', '32503', '18086', '55004', '65795', '82926', '75725', '52917', '75463', '82202', '35158', '67065', '38454', '90106', '79681', '57317', '68357', '66487', '99640', '13182', '68684', '96739', '89887', '54307', '98357', '4597', '47645', '38560', '17334', '46291', '91096', '22675', '12995', '35767', '76173', '54754', '75206', '13345', '78860', '19929', '12740', '13007', '69737', '52454', '6784', '77198', '59565', '44548', '22924', '38773', '9522', '59392', '45244', '64754', '39640', '75795', '22725', '78314', '24738', '83167', '31049', '92122', '62117', '47314', '34032', '76951', '63164', '22515', '46057', '81625', '72164', '60013', '26171', '55608', '50486', '51422', '18277', '13682', '70130', '49689', '32278', '25430', '84394', '57371', '93398', '14139', '461', '37302', '25705', '25642', '70311', '81778', '66948', '51187', '99649', '44509', '12753', '39827', '57393', '40288', '26496', '1500', '32979', '62062', '5170', '25273', '26343', '21058', '66749', '52257', '26335', '4347', '82427', '51381', '66857', '58330', '15097', '23881', '93865', '97929', '11233', '67910', '22731', '70911', '93941', '46169', '31920', '16027', '1635', '16338', '49712', '29345', '26316', '15221', '54771', '34715', '35399', '80287', '90881', '33758', '46569', '52450', '40564', '34885', '5679', '53232', '85632', '87510', '4008', '87014', '49611', '94569', '96432', '57394', '66064', '34144', '67269', '83546', '5901', '25386', '57588', '55055', '6940', '8414', '31432', '75407', '86922', '33925', '24600', '48261', '94439', '34234', '69028', '37145', '32386', '68275', '13237', '3521', '57395', '55029', '16426', '87797', '18559', '72744', '1155', '30384', '19799', '50001', '85831', '19583', '83898', '13465', '58160', '51160', '89216', '90725', '37151', '32241', '6319', '95146', '10376', '55137', '64094', '14990', '19747', '85852', '50692', '63214', '53123', '97058', '60203', '29272', '14439', '69712', '13023', '75808', '67150', '76276', '54521', '46621', '78807', '89302', '30273', '85103', '63180', '75468', '98474', '37749', '66275', '61712', '39381', '2740', '83025', '18083', '42030', '3391', '56204', '3960', '34780', '22476', '50074', '79854', '89447', '3695', '2986', '85090', '71529', '77995', '51572', '60278', '69314', '70777', '46754', '22085', '94517', '98052', '5700', '43157', '12345', '34663', '40350', '5739', '84384', '8354', '81566', '75500', '88934', '67062', '52877', '30428', '95593', '13288', '51836', '25264', '19278', '81290', '47555', '7606', '46694', '29735', '25723', '81597', '26221', '24545', '98576', '63395', '36061', '58752', '8486', '97817', '27235', '18579', '2387', '88017', '42855', '5111', '49094', '28448', '82227', '63436', '89135', '86591', '2922', '72163', '83000', '14378', '81829', '5610', '93513', '78135', '55292', '80776', '21212', '40604', '44442', '50505', '22750', '47985', '19367', '63494', '4363', '64500', '79444', '36504', '43418', '72523', '85981', '13740', '302', '76267', '14962', '79643', '26144', '27125', '13364', '82935', '8936', '8340', '38025', '80742', '42829', '95357', '11131', '6806', '10497', '70527', '3004', '54217', '51051', '34722', '57348', '50489', '76514', '76546', '29498', '40587', '52697', '37808', '32509', '68927', '68051', '53328', '41926', '9344', '67795', '98626', '44058', '46817', '95773', '57539', '13352', '96292', '72647', '47111', '48595', '82684', '43566', '93381', '3081', '27653', '25045', '34753', '80870', '92013', '21935', '89454', '14127', '73278', '87015', + '65232', '97216', '26840', '21272', '8226', '42347', '44358', '26715', '7860', '31989', '14091', '15648', '85801', '20463', '85221', '77969', '87196', '28563', '69663', '55169', '11372', '38915', '74678', '1183', '14845', '85696', '54995', '62342', '83227', '73536', '64251', '46556', '78421', '89058', '41036', '79746', '42148', '77720', '33923', '24979', '98428', '80202', '36845', '20584', '13506', '97375', '48434', '14863', '29237', '99014', '20650', '48496', '61825', '89100', '51501', '22632', '89030', '22901', '54072', '68093', '98140', '1631', '43266', '34532', '35780', '17763', '41731', '19580', '72266', '66530', '55650', '51506', '92256', '5332', '85143', '65002', '30530', '21358', '88420', '81349', '94086', '68143', '95343', '30490', '61605', '40296', '61665', '21032', '498', '67165', '3151', '94788', '36502', '77434', '88776', '67565', '4404', '51177', '49030', '88502', '92552', '31170', '92051', '79960', '43784', '17864', '54179', '91590', '39153', '75017', '11161', '31100', '27964', '30263', '54908', '57991', '89272', '14642', '40576', '20224', '48887', '93479', '87862', '19858', '78238', '4113', '32369', '70072', '82752', '85122', '72450', '53113', '53806', '45347', '55032', '77242', '70401', '83685', '41229', '47489', '36964', '40556', '2619', '64080', '7354', '10159', '74827', '11846', '64587', '88667', '20940', '93594', '43669', '38592', '20211', '96055', '65995', '89957', '18941', '82750', '90753', '49989', '63331', '52911', '1675', '98447', '35516', '28539', '91592', '80615', '68066', '63922', '52509', '26025', '14634', '69439', '19820', '89983', '38306', '84048', '66264', '26855', '3634', '92094', '61088', '28293', '11428', '68748', '10665', '27114', '20151', '65883', '86423', '77069', '74997', '147', '41427', '26124', '22163', '82452', '61186', '89370', '58583', '2692', '54969', '84679', '26237', '46229', '16041', '28473', '38684', '43587', '37886', '68790', '92030', '85066', '13673', '30280', '91844', '43115', '10005', '1481', '84393', '10008', '60291', '90687', '99338', '95570', '39916', '68643', '41309', '24724', '57188', '75473', '21647', '50206', '6820', '73756', '51102', '76169', '99840', '32863', '17306', '43063', '90483', '15894', '59042', '53797', '93961', '12248', '12125', '39393', '17056', '11576', '6145', '43960', '74245', '86805', '95665', '58855', '50039', '14867', '85076', '3939', '55501', '18184', '62019', '16312', '37518', '18544', '67431', '68250', '70766', '74635', '41835', '74538', '77822', '47918', '90863', '17526', '78930', '47473', '67945', '70385', '19404', '45030', '13476', '46186', '28191', '22019', '18700', '90915', '41408', '63333', '52902', '87336', '72833', '47707', '46692', '47873', '82012', '22597', '46379', '69109', '72108', '47439', '51130', '41894', '29827', '88403', '75040', '37504', '69925', '19034', '57998', '46633', '1021', '48358', '55923', '3536', '26350', '36696', '29658', '25247', '65614', '19042', '34463', '85938', '26155', '49801', '74604', '17581', '91632', '12935', '97966', '14947', '71196', '32270', '51915', '41692', '83274', '6608', '37190', '35363', '85313', '97545', '5696', '23700', '39334', '38434', '20192', '27349', '71340', '19732', '96142', '17152', '32995', '34829', '71157', '36376', '11522', '26646', '19239', '34033', '4200', '39023', '64291', '7931', '42807', '2800', '75490', '4515', '84571', '59557', '13421', '69465', '69121', '82358', '18134', '18536', '74294', '24013', '43777', '94192', '77031', '33341', '98070', '27534', '34419', '40107', '17826', '48196', '82843', '37592', '40484', '49019', '59822', '26118', '89788', '5990', '99595', '35178', '49473', '54699', '81618', '23497', '87025', '29421', '1685', '31406', '54115', '25193', '44525', '44886', '4885', '74482', '63280', '57532', '29773', '83104', '5354', '35313', '12558', '16165', '52712', '82282', '73541', '97334', '7283', '29405', '87694', '64717', '98840', '2868', '17727', '61847', '32417', '91009', '12117', '35077', '36279', '87552', '12441', '70576', '505', '57332', '56191', '33846', '78645', '58506', '48692', '27712', '86722', '46677', '81512', '14807', '30337', '7863', '457', '71893', '32256', '21897', '95811', '73552', '24929', '4893', '49448', '33836', '24781', '43236', '30853', '81985', '60625', '20087', '30674', '39280', '10779', '97785', '11298', '65057', '17589', '44085', '10126', '72351', '4165', '30539', '97124', '20545', '50087', '13490', '4055', '62365', '24046', '63110', '99045', '47122', '74389', '29843', '89082', '71686', '40321', '15789', '63062', '23403', '27718', '72550', '36098', '47309', '60568', '22266', '20542', '59018', '76386', '89381', '9164', '42093', '19931', '90426', '73695', '26948', '17363', '15727', '75439', '45425', '42518', '32966', '80703', '4659', '74566', '22464', '49383', '53167', '80720', '45464', '179', '29789', '19444', '97663', '6466', '51290', '56374', '17869', '97520', '45148', '92149', '54757', '94455', '80125', '98584', '70174', '77708', '59260', '50275', '49211', '60730', '29875', '90935', '29676', '95390', '18263', '73189', '41364', '39707', '75110', '59156', '11770', '38655', '55173', '62547', '16328', '70585', '81958', '61191', '90906', '45978', '59134', '24609', '32956', '30518', '27341', '84512', '24987', '65295', '75210', '97931', '56717', '6751', '83338', '82808', '96570', '27038', '93274', '399', '9330', '54319', '24848', '39269', '92692', '50625', '52306', '93262', '48756', '66694', '50517', '41763', '42231', '8589', '41923', '87839', '9579', '5104', '41634', '63030', '15100', '59593', '38288', '88852', '81957', '84267', '56380', '89329', '74372', '16026', '15795', '29456', '93173', '76367', '37598', '68153', '72405', '55181', '77543', '30730', '27564', '98764', '48711', '22180', '51352', '80150', '50091', '19481', '97962', '74879', '75369', '84410', '54712', '68399', '60910', '57922', '8896', '94118', '5276', '54049', '11614', '98854', '65979', '75156', '39456', '30226', '27357', '71087', '30814', '6416', '56480', '70259', '56525', '69945', '63874', '87262', '97398', '77972', '76745', '97191', '26739', '10957', '48743', '18175', '74688', '49853', '83675', '79232', '72211', '77255', '44445', '81053', '5506', '21366', '99015', '57598', '9467', '65131', '73794', '25679', '3609', '70041', '14653', '93792', '7076', '87326', '12978', '20886', '24089', '82187', '55203', '96649', '51205', '26250', '98219', '64275', '18634', '94004', '50999', '99611', '72380', '28685', '33246', '49116', '44972', '44273', '26558', '84799', '51310', '39480', '16713', '34371', '94308', '38743', '14592', '47430', '74505', '38866', '69596', '84705', '20236', '49353', '28259', '16255', '27665', '94271', '98652', '18279', '4805', '57471', '7944', '72567', '55603', '47327', '32268', '1256', '47608', '80225', '15744', '75492', '74652', '96812', '77976', '72595', '86791', '97736', '83149', '57030', '58553', '7121', '53544', '94894', '57236', '55850', '52762', '36303', '97740', '25314', '43196', '74248', '52320', '60448', '10606', '7010', '21765', '20357', '61825', '34331', '15898', '67485', '70353', '41657', '49212', '21628', '11783', '90514', '33883', '85668', '73432', '55374', '53880', '864', '66975', '51190', '18268', '45344', '99680', '91098', '3893', '90773', '55611', '5914', '14977', '29463', '38339', '94390', '15379', '74717', '78721', '10689', '90966', '33191', '32384', '4363', '61992', '37456', '28402', '51633', '14358', '99226', '23024', '22114', '86438', '70682', '27242', '46237', '92467', '83997', '71994', '59256', '44728', '51372', '50328', '66925', '16487', '7348', '69501', '23328', '55945', '98064', '92561', '5275', '67097', '37616', '8561', '14378', '83858', '44306', '60514', '89238', '28781', '11864', '31540', '3809', '16629', '4336', '70961', '10787', '58719', '39587', '46840', '48993', '18578', '30890', '71438', '29672', '54785', '77570', '25012', '70696', '25935', '279', '74327', '33944', '55060', '72194', '28269', '47600', '2132', '56618', '77029', '26410', '25682', '13744', '31968', '27115', '57065', '49313', '31237', '70475', '38549', '33723', '66622', '19646', '93518', '4052', '29390', '10163', '19879', '10765', '71024', '71339', '69114', '78385', '64440', '79577', '48109', '81114', '4708', '44863', '72410', '71161', '55491', '3433', '88675', '48496', '97875', '17184', '840', '16960', '32880', '48533', '82430', '44005', '36654', '96011', '16158', '21530', '88485', '91231', '77831', '39266', '9833', '96154', '89200', '2021', '57813', '897', '27643', '65750', '27447', '29043', '50691', '74683', '78027', '99590', '6052', '22867', '4567', '3918', '27143', '77750', '32003', '14011', '59006', '33140', '12165', '72413', '89931', '59389', '45281', '52596', '31993', '88613', '85332', '8016', '34419', '80901', '76317', '34932', '71099', '23354', '19296', '42671', '12646', '47189', '67982', '79803', '28449', '6229', '44873', '48970', '10012', '6871', '88240', '1277', '71039', '47959', '45051', '74358', '68394', '49093', '78063', '26981', '8704', '18470', '14458', '38195', '75691', '64683', '44910', '93423', '67591', '36833', '63204', '29507', '38894', '59524', '12141', '36543', '86914', '91250', '45459', '30156', '119', '95390', '75872', '28827', '67609', '99869', '91237', '70358', '60292', '3499', '3133', '45478', '5800', '47576', '50558', '71500', '65579', '84252', '68999', '59495', '79395', '28634', '44121', '26503', '11922', '22058', '34164', '32668', '10422', '62793', '41303', '2030', '76875', '17151', '42101', '22133', '82998', '19499', '14247', '95259', '746', '38449', '72450', '99138', '61259', '65623', '13439', '45597', '55234', '19347', '70266', '4828', '79316', '16983', '49723', '95468', '9747', '81126', '31999', '33796', '15270', '60644', '61048', '98848', '26685', '40980', '23733', '13676', '98363', '17970', '76451', '42657', '13165', '27870', '49193', '56279', '34647', '1652', '47674', '95555', '80556', '52419', '61110', '26124', '49097', '90600', '53605', '97544', '8694', '94739', '59652', '41807', '87155', '83539', '61468', '20614', '12652', '86562', '82894', '94360', '56182', '30513', '65379', '6522', '86486', + '37674', '44977', '54370', '97381', '60218', '2423', '99591', '69913', '26507', '19708', '6279', '58955', '20126', '1495', '57894', '7638', '38700', '77148', '36844', '7539', '91452', '6914', '74349', '66850', '49104', '6516', '58535', '20851', '27859', '32881', '72919', '28203', '32882', '2419', '77583', '63822', '37703', '66793', '65784', '62281', '55867', '70703', '89344', '1498', '33770', '87176', '95636', '64891', '90736', '95521', '10989', '5237', '99010', '21106', '11422', '1831', '67239', '52557', '36468', '71713', '39637', '49574', '50455', '14953', '96900', '70852', '96982', '4341', '44585', '95651', '79669', '29652', '87294', '74692', '16221', '768', '35380', '21352', '50907', '27259', '11718', '5017', '55964', '94137', '52347', '10595', '12968', '85602', '97965', '18836', '90511', '70960', '97336', '44575', '23791', '42195', '64776', '29363', '42379', '1805', '28919', '6772', '78143', '54797', '27362', '56149', '59048', '38567', '6339', '27787', '42167', '45990', '95532', '54839', '26572', '38496', '89797', '6634', '16468', '24898', '66814', '98126', '31762', '36133', '64539', '43167', '87022', '61295', '30364', '89249', '25756', '63570', '91484', '10564', '79648', '5756', '41376', '61897', '40388', '88927', '62891', '79708', '25495', '22204', '33892', '36871', '19879', '58646', '57061', '73100', '75831', '20029', '67462', '54675', '7766', '2409', '24506', '7877', '11720', '86252', '9897', '8080', '70684', '74497', '2242', '24604', '31969', '83999', '56635', '5283', '64971', '79152', '27470', '89042', '22835', '21476', '50292', '56081', '96342', '32763', '84487', '64856', '79152', '64656', '72169', '69971', '93094', '52804', '80917', '53152', '56016', '28496', '79110', '17133', '12581', '91742', '78929', '2676', '46700', '59528', '93808', '4535', '54035', '40161', '62796', '3598', '97088', '13599', '36337', '73395', '17494', '86275', '62058', '61937', '87747', '94883', '90677', '88544', '72553', '50210', '75481', '64378', '74464', '21659', '30970', '71989', '84846', '72289', '88716', '39143', '8487', '4912', '91013', '18623', '19122', '36507', '76438', '7516', '67970', '72350', '69873', '33635', '55983', '69008', '49545', '3134', '60056', '52509', '63304', '15560', '23651', '81090', '7027', '8317', '33060', '37295', '51961', '53037', '97431', '40512', '23536', '25168', '78455', '85613', '12304', '40733', '99890', '51238', '55439', '96201', '73559', '92533', '90173', '16721', '6078', '29854', '38894', '31117', '63040', '86795', '81786', '21149', '38998', '61811', '48622', '73019', '59296', '13576', '92559', '36300', '77294', '26794', '50912', '98380', '13176', '57746', '75286', '15330', '40921', '7337', '4664', '20384', '4674', '44516', '27633', '31950', '88210', '54536', '9839', '80137', '77491', '18434', '45152', '96942', '41005', '76103', '34825', '86869', '14772', '13384', '21051', '37348', '34434', '97210', '54960', '26598', '60981', '41889', '6446', '64492', '95310', '86236', '81885', '35684', '16539', '98476', '32028', '96470', '6318', '99576', '93935', '48609', '86090', '2476', '65576', '80636', '44817', '99646', '98963', '20486', '26261', '27334', '72946', '82023', '33506', '80193', '13762', '98133', '21134', '33268', '63477', '74609', '30454', '51477', '93391', '96805', '68653', '2714', '63642', '51520', '22972', '13305', '96058', '42336', '74461', '31597', '12050', '81712', '37977', '25718', '4834', '56608', '75731', '406', '28585', '63924', '23702', '29849', '16941', '91921', '65842', '76525', '68534', '50902', '17609', '23852', '53703', '31286', '58526', '9633', '87596', '10654', '2085', '52766', '22135', '76524', '32295', '90072', '70078', '77786', '93741', '87320', '70309', '44024', '95286', '12361', '29682', '59766', '26685', '90686', '81691', '49704', '23431', '53955', '39023', '47261', '1530', '58265', '80065', '95620', '90621', '63760', '90676', '81653', '36397', '20252', '81754', '20256', '67098', '7838', '49408', '88400', '87941', '84533', '6570', '22567', '18850', '55472', '40129', '48425', '23497', '39308', '34698', '53092', '89480', '47785', '57282', '25508', '19006', '50604', '86917', '9436', '88921', '3168', '70537', '3185', '34988', '5462', '69482', '45768', '91955', '56898', '15307', '99731', '89292', '19356', '20646', '66712', '7281', '12856', '31174', '19577', '8726', '62971', '33008', '37118', '59055', '84101', '68445', '91957', '47526', '15627', '79914', '20013', '26147', '80821', '56372', '74205', '28531', '25352', '51775', '93948', '55212', '17863', '91521', '74911', '88160', '2360', '98260', '18294', '62402', '84268', '9580', '42668', '1467', '40059', '5221', '4216', '9917', '35420', '16496', '34369', '50253', '95234', '95114', '84193', '28322', '37031', '81284', '88628', '36782', '42572', '73347', '66188', '43342', '77285', '16513', '89064', '63066', '72645', '67075', '48208', '18181', '77898', '65795', '53707', '39856', '92883', '92567', '49733', '30236', '10273', '53029', '69773', '78379', '72108', '47696', '97557', '95184', '14688', '29853', '62694', '70431', '88435', '58799', '21883', '99866', '69178', '55870', '14414', '85274', '27321', '55555', '613', '15067', '88217', '73655', '99548', '13631', '78789', '36690', '7952', '60830', '77438', '40059', '95602', '43097', '3429', '93731', '90537', '2932', '35702', '16125', '6652', '39632', '39349', '9910', '38103', '78608', '73565', '48556', '28978', '7128', '82326', '53980', '28059', '28212', '87101', '77752', '99170', '56753', '30484', '71470', '32607', '24674', '32687', '25098', '94712', '64024', '48239', '90408', '17316', '99243', '3656', '67402', '48009', '98427', '52800', '56024', '4417', '89747', '93338', '18758', '56411', '44810', '82456', '30808', '75470', '67115', '66876', '53906', '78403', '56059', '34383', '60056', '89136', '7237', '11129', '21351', '78662', '43606', '37454', '45465', '9292', '38099', '81699', '50195', '49368', '47503', '44605', '6523', '81478', '37910', '397', '20256', '6835', '2787', '80383', '4241', '65986', '83870', '21205', '10879', '26593', '44357', '72604', '56131', '43423', '80206', '26240', '87198', '99445', '53504', '10632', '2465', '31793', '89575', '64184', '39988', '60049', '87100', '37151', '61585', '82180', '52065', '72519', '72935', '3201', '5862', '20560', '95339', '21661', '17533', '17182', '71189', '91564', '57999', '35490', '94773', '95056', '51583', '59394', '10727', '8655', '48123', '10701', '25314', '20100', '6533', '46435', '43188', '23001', '23018', '76637', '32018', '36603', '18701', '9550', '61550', '47541', '36500', '67507', '81574', '95490', '69169', '32584', '30045', '64699', '83539', '89396', '42517', '61979', '41528', '8271', '88377', '61423', '1158', '89724', '70789', '14886', '64823', '56675', '97747', '23990', '58495', '82064', '17062', '90258', '86854', '93304', '12925', '49975', '45074', '87155', '72223', '67344', '42733', '42516', '40110', '15444', '88285', '39371', '23198', '61544', '90205', '6192', '15718', '19803', '92712', '20081', '31397', '5555', '70463', '19521', '80401', '74097', '32060', '26495', '20507', '40473', '1449', '57215', '46142', '39303', '50359', '35898', '46908', '90752', '7823', '27416', '73770', '98790', '17907', '29999', '76417', '49926', '76752', '21608', '26524', '88209', '6000', '88897', '19541', '41451', '59538', '56560', '1456', '67828', '82407', '45722', '93344', '54279', '78594', '38354', '93807', '10929', '91560', '60681', '70615', '32527', '10108', '48303', '63134', '28500', '18257', '57081', '24801', '99077', '52197', '15390', '52300', '57116', '417', '7503', '20054', '75315', '81359', '69091', '18853', '2465', '25600', '13522', '74575', '12661', '83071', '15191', '27543', '21730', '60853', '18961', '14773', '89185', '33694', '51143', '1449', '68831', '78062', '65173', '32697', '41674', '9429', '22156', '96022', '46305', '97534', '5685', '48870', '89988', '20686', '66705', '6865', '94250', '16872', '13178', '7420', '73531', '92723', '60620', '48843', '74207', '60016', '50943', '62699', '63507', '76537', '87066', '76922', '24711', '34809', '5021', '31293', '53854', '77607', '52322', '10934', '50284', '87804', '36730', '86946', '80749', '43325', '97958', '7362', '39582', '10042', '42053', '66236', '69931', '23463', '87996', '33563', '4468', '32905', '50815', '79478', '28658', '46018', '23186', '26080', '13494', '6237', '42762', '86440', '77407', '10426', '62902', '73251', '36861', '92357', '98754', '1839', '46391', '11420', '27132', '93028', '39609', '42015', '68218', '54228', '5456', '38705', '64307', '49483', '878', '54360', '54480', '66684', '55089', '4537', '82073', '72602', '96238', '56708', '58625', '32991', '74205', '72868', '79086', '64250', '56376', '10621', '76607', '47706', '72760', '70303', '60715', '14644', '44186', '36264', '29489', '14184', '62699', '30567', '16700', '31222', '15650', '1500', '22950', '54628', '41004', '96094', '70028', '74178', '65328', '26605', '63076', '75271', '79285', '8151', '42101', '56362', '25961', '87864', '972', '29510', '2747', '8877', '9780', '61052', '84105', '15573', '27475', '44570', '25334', '18517', '44237', '84094', '67524', '76761', '65678', '79284', '2462', '42631', '22696', '19223', '29728', '67742', '11883', '59027', '12377', '80538', '2165', '17377', '15030', '49838', '23920', '26025', '68179', '75894', '43783', '97106', '75558', '35528', '52081', '16951', '68855', '402', '21459', '97550', '16948', '5369', '4641', '2663', '15233', '79974', '71093', '15234', '42690', '22322', '54282', '95845', '90010', '40530', '88298', '41885', '7079', '6098', '72786', '36603', '77378', '48393', '45723', '41996', '96025', '89297', '75586', '8422', '24360', '170', '46036', '46725', '67944', '74029', '73069', '45371', '99916', '71085', '42608', '89904', '6393', '51274', '42729', '58924', '82497', '64143', '88622', '18818', '89041', '56090', '21369', '78224', '90450', '45488', '58830', '4133', '98062', '81113', '11285', '51457', '3183', '38800', '65278', '42169', '28602', '52648', '44683', '75647', '11778', '32151', '33528', '23773', '68268', '23367', '70964', '23548', + '35575', '67570', '77681', '74158', '25374', '62714', '43100', '4977', '51678', '83460', '29755', '15890', '64626', '54044', '14793', '64339', '94008', '97126', '49202', '33889', '12601', '12275', '56123', '94557', '68226', '67200', '9374', '70687', '29211', '8039', '14598', '74548', '37433', '98991', '29933', '37203', '23973', '96482', '64774', '58350', '61781', '31824', '57193', '26476', '21814', '32297', '32627', '44277', '33876', '55468', '81715', '82505', '61462', '20324', '84293', '40116', '51087', '43594', '6854', '59077', '39841', '26023', '22777', '66859', '82460', '89515', '41712', '33711', '71875', '10685', '12655', '50138', '31063', '37040', '95819', '38919', '27391', '29833', '34350', '65646', '7697', '2688', '41146', '13241', '50305', '86568', '24487', '78741', '96370', '21015', '31719', '39750', '25014', '72415', '8486', '90668', '51143', '49488', '21057', '92803', '53528', '39550', '76039', '44185', '32404', '30217', '19796', '38084', '49161', '80140', '20241', '39357', '68908', '93083', '77231', '6952', '36322', '50790', '623', '29730', '13616', '57546', '17434', '93811', '35148', '81419', '40250', '40329', '89126', '72402', '16053', '27107', '28919', '16829', '96582', '65057', '28416', '30801', '77742', '27420', '73118', '89352', '54706', '23035', '88413', '64608', '61930', '15037', '47327', '59596', '18700', '57576', '63628', '56823', '60091', '68209', '21001', '14962', '72257', '83802', '33721', '86343', '11133', '65737', '68477', '90725', '86869', '98403', '47393', '25356', '61372', '8873', '19888', '48836', '66005', '23531', '72520', '26461', '78508', '28213', '96394', '22983', '37856', '71814', '27425', '72753', '27511', '65471', '38592', '3683', '24652', '64505', '92543', '53201', '40639', '99542', '53425', '35321', '47669', '14134', '47727', '48202', '71931', '32119', '50086', '50266', '67159', '89317', '81905', '30315', '49154', '8690', '69365', '56881', '46473', '64100', '38365', '59377', '65630', '54871', '52745', '91536', '16106', '70066', '62063', '84530', '88103', '33599', '51063', '87299', '41880', '25335', '51252', '42788', '13568', '1721', '62424', '83308', '36787', '91536', '92555', '27600', '24030', '12267', '66336', '30242', '7183', '67624', '28471', '48593', '79766', '31178', '47818', '94522', '88855', '45262', '43670', '18065', '25062', '44558', '37189', '69225', '35216', '42683', '26289', '72816', '31947', '65871', '45715', '59452', '22014', '56669', '60331', '33450', '60601', '95047', '30789', '90107', '81565', '32266', '3252', '5446', '58756', '55370', '34034', '81071', '2560', '39054', '39564', '15010', '5389', '60002', '53320', '49545', '48444', '31415', '39278', '79879', '30148', '10186', '60358', '29011', '14419', '95159', '94815', '55251', '90910', '80582', '92304', '11697', '60061', '38577', '84439', '76196', '34542', '50963', '36294', '11123', '59763', '29873', '47383', '12979', '22119', '21723', '64725', '48377', '77132', '9817', '79920', '47653', '60069', '12924', '53808', '55962', '66969', '13757', '60615', '10994', '9138', '34119', '58436', '64407', '75170', '73524', '51864', '94183', '86847', '15585', '57616', '96267', '5340', '52929', '49096', '50291', '5559', '32382', '84077', '6598', '87921', '59719', '31726', '44772', '63373', '75420', '66829', '47275', '98264', '61387', '94945', '44540', '50098', '13078', '44729', '95332', '63555', '30782', '63203', '15071', '60996', '72812', '17418', '80215', '37610', '30670', '44674', '74822', '15471', '25236', '16266', '76213', '35820', '19567', '8715', '72003', '90606', '1434', '53545', '88170', '75014', '62287', '35436', '38669', '12927', '83877', '38622', '28313', '82884', '73969', '38671', '10450', '24158', '22941', '73162', '86548', '42482', '95315', '92016', '96156', '44012', '35962', '6366', '3881', '74300', '26248', '30182', '19164', '67105', '66771', '52587', '69894', '61820', '16551', '50743', '10096', '69030', '24451', '89165', '23929', '96291', '30685', '64413', '19913', '9049', '71383', '61684', '45384', '45927', '81840', '49521', '89594', '30055', '83430', '14930', '60316', '86585', '99375', '80170', '14207', '19584', '20067', '82874', '30159', '46647', '6942', '66777', '32638', '55662', '75470', '77622', '26893', '96149', '14373', '33252', '50574', '7945', '20696', '56662', '94348', '3384', '20956', '89668', '99052', '65131', '56847', '17589', '16419', '2670', '10705', '59587', '92902', '92424', '48570', '11034', '69149', '35733', '17315', '84966', '69353', '69590', '52834', '32561', '6049', '50156', '71676', '76423', '32361', '61509', '8845', '75709', '35956', '21912', '31188', '59083', '43459', '38614', '92206', '55645', '38737', '34193', '6451', '94163', '24326', '49976', '71600', '58024', '67160', '4365', '38270', '59558', '80834', '60739', '54318', '19738', '42196', '43191', '13463', '88914', '99239', '66869', '75691', '33085', '4323', '7170', '46184', '41423', '89835', '46877', '20349', '14365', '32727', '35322', '841', '23597', '43370', '57527', '73250', '32553', '71489', '44617', '98323', '37672', '59549', '96023', '63176', '13524', '15621', '30448', '28136', '45549', '3513', '64153', '19839', '24219', '41987', '51083', '90268', '52052', '31430', '4727', '99409', '43595', '82374', '61251', '51470', '66562', '98724', '23529', '53895', '67562', '87573', '89964', '30821', '15733', '33062', '86963', '33450', '75338', '32570', '14453', '38080', '36335', '84226', '52790', '42883', '61156', '42789', '57846', '60096', '29946', '80178', '15882', '1971', '60722', '62458', '8754', '59991', '89321', '584', '70565', '36458', '21226', '23561', '9837', '39364', '23065', '30675', '9306', '40085', '52082', '89976', '73283', '77851', '36174', '54470', '63250', '72111', '70853', '26723', '42590', '91230', '47512', '13983', '70898', '70927', '40721', '30642', '41628', '90010', '27306', '1933', '43304', '44499', '87890', '22201', '89249', '63935', '48438', '58588', '1061', '70061', '63075', '9676', '65820', '82156', '82668', '111', '54350', '10328', '23466', '98936', '18285', '53919', '32422', '84859', '58387', '24022', '32423', '6010', '56417', '49452', '69999', '14885', '47102', '59577', '24999', '75984', '96464', '59088', '85987', '71442', '88789', '4753', '8229', '76883', '15284', '90610', '40507', '78882', '55575', '25315', '7214', '70602', '4796', '35767', '54657', '42153', '16050', '93607', '99249', '77236', '59949', '52871', '47837', '33534', '30023', '89137', '99938', '35824', '50775', '30282', '82798', '53312', '65277', '68375', '91445', '58166', '43344', '6589', '82515', '34632', '78588', '152', '67554', '15877', '74334', '32783', '45147', '39483', '92067', '59029', '38298', '55229', '28268', '85140', '33451', '15424', '46695', '23201', '83329', '28372', '19518', '89198', '33305', '43892', '470', '37662', '9407', '14376', '80310', '21459', '72381', '80414', '88305', '69073', '63101', '91054', '47190', '48595', '24696', '41426', '35133', '94399', '21790', '55040', '73279', '20809', '67805', '94115', '58633', '78053', '89444', '4112', '8', '34517', '22106', '85934', '86814', '53333', '93437', '85062', '32791', '72744', '99843', '51161', '22730', '34908', '82918', '92566', '22467', '41226', '98518', '29235', '94042', '84371', '79100', '25214', '7764', '59427', '47891', '61092', '23775', '13641', '30837', '77377', '43032', '38441', '29462', '20300', '19070', '20982', '73987', '87836', '68062', '6419', '51563', '40084', '85694', '86677', '47142', '27222', '17844', '19158', '45120', '88524', '74724', '73229', '42470', '38751', '1132', '28603', '61188', '55021', '88825', '58005', '62411', '8843', '94852', '93664', '39253', '27473', '247', '43824', '1804', '8905', '11509', '95659', '7811', '80691', '15779', '49794', '8991', '76099', '29223', '36060', '85399', '41369', '22885', '38473', '22376', '50446', '89578', '25818', '61333', '78787', '47605', '83654', '99068', '52120', '48367', '86381', '19803', '72600', '31998', '37755', '88031', '83969', '42319', '27974', '35780', '93662', '46808', '60529', '15491', '10447', '48829', '33886', '68333', '44855', '86554', '64794', '66376', '58222', '14021', '52043', '56375', '1300', '38105', '89159', '97456', '26800', '93124', '3673', '32279', '30658', '84475', '3708', '93952', '39245', '91980', '55333', '79440', '64407', '46559', '60759', '10688', '49872', '45810', '87405', '66932', '56530', '57751', '9619', '27361', '6356', '65848', '7524', '20273', '22362', '20504', '28042', '39475', '51677', '85733', '32426', '54558', '17222', '56485', '34928', '90917', '70528', '51732', '61014', '98420', '67265', '41383', '3883', '47642', '53324', '93679', '93088', '57534', '44449', '46779', '81482', '54279', '80135', '11216', '92545', '18426', '96005', '57801', '21898', '5104', '83467', '72015', '43783', '89674', '57468', '96686', '95167', '38507', '95187', '64923', '71214', '42834', '93219', '47342', '24476', '84834', '29080', '86533', '30687', '68400', '26933', '37396', '65169', '89767', '20642', '53843', '85167', '77306', '46723', '68501', '4243', '35044', '15950', '40388', '53630', '76125', '10816', '83285', '4120', '11402', '91344', '95169') + + SELECT (rand(), rand()) IN tuple(tuple(17258, 93148), tuple(4508, 52749), tuple(68660, 70017), tuple(77797, 23528), tuple(1136, 37393), tuple(53237, 15379), tuple(68370, 73211), tuple(15782, 54962), tuple(59432, 45415), tuple(68396, 920), tuple(96154, 21016), tuple(12700, 26887), tuple(88016, 43191), tuple(68153, 51575), tuple(91315, 40005), tuple(18070, 73178), tuple(86, 631), tuple(77717, 20324), tuple(3227, 76188), tuple(74960, 43147), tuple(77538, 19628), tuple(82292, 6525), tuple(24293, 12566), tuple(85244, 96287), tuple(93982, 1329), tuple(38064, 54723), tuple(83999, 45810), tuple(71921, 53673), tuple(88638, 9669), tuple(1959, 39535), tuple(82235, 95796), tuple(27907, 90975), tuple(42383, 91015), tuple(9948, 91514), tuple(81712, 47309), tuple(400, 25808), tuple(31791, 46948), tuple(39740, 36098), tuple(25943, 84598), tuple(99598, 52939), tuple(77134, 15845), tuple(40313, 72174), tuple(85017, 94036), tuple(36595, 14303), tuple(83961, 68078), tuple(55792, 72759), tuple(73574, 43606), tuple(9853, 63560), tuple(28580, 56721), tuple(74804, 41025), tuple(32095, 55657), tuple(52881, 63416), tuple(91368, 90310), tuple(23922, 38883), tuple(30592, 10758), tuple(66448, 61183), tuple(31880, 96697), tuple(11362, 20633), tuple(75331, 2015), tuple(71129, 8785), tuple(1115, 70955), tuple(7886, 83698), tuple(18961, 84556), tuple(16677, 43028), tuple(37347, 70220), tuple(31699, 71244), tuple(10578, 96159), tuple(67600, 39041), tuple(78791, 86687), tuple(21545, 54174), tuple(68774, 37637), tuple(46132, 81768), tuple(98413, 20605), tuple(2960, 23665), tuple(31507, 35719), tuple(96209, 18368), tuple(60558, 38035), tuple(21952, 3264), tuple(11834, 86458), tuple(21651, 17650), tuple(86276, 36087), tuple(18818, 24849), tuple(61951, 3390), tuple(59637, 62545), tuple(30346, 72253), tuple(36281, 2992), tuple(78340, 49872), tuple(94326, 93723), tuple(3416, 94405), tuple(12272, 8741), tuple(22600, 22095), tuple(57636, 37106), tuple(38702, 14889), tuple(70238, 11276), tuple(17325, 60648), tuple(16492, 41271), tuple(52100, 1304), tuple(93416, 7795), tuple(57209, 71008), tuple(48010, 36078), tuple(20384, 74420), tuple(77440, 34439), tuple(69224, 45099), tuple(30374, 33884), tuple(49038, 90140), tuple(1154, 84725), tuple(64926, 86985), tuple(91746, 73472), tuple(59757, 75755), tuple(45860, 71557), tuple(45833, 36526), tuple(74618, 73598), tuple(91360, 65168), tuple(58029, 30793), tuple(56332, 14973), tuple(99943, 96877), tuple(97454, 6450), tuple(64502, 77301), tuple(73182, 31853), tuple(76809, 83964), tuple(82916, 86188), tuple(78736, 65427), tuple(36495, 7422), tuple(76196, 2804), tuple(96117, 61093), tuple(9177, 26099), tuple(52942, 63007), tuple(48578, 47876), tuple(50638, 89903), tuple(7113, 97316), tuple(35301, 12750), tuple(47807, 7254), tuple(38217, 55418), tuple(56970, 41687), tuple(20527, 62886), tuple(358, 14021), tuple(64018, 18582), tuple(91740, 21683), tuple(81967, 53589), tuple(45437, 38450), tuple(45476, 67752), tuple(76851, 72072), tuple(7304, 60091), tuple(40097, 12897), tuple(39906, 29247), tuple(84262, 58734), tuple(30857, 43791), tuple(56087, 78929), tuple(20498, 45954), tuple(48726, 500), tuple(62723, 43763), tuple(28368, 30756), tuple(74048, 52403), tuple(15045, 95926), tuple(75542, 55384), tuple(52543, 22525), tuple(56001, 6935), tuple(11431, 46745), tuple(77731, 7310), tuple(36718, 59909), tuple(32235, 91254), tuple(92417, 25917), tuple(21782, 79277), tuple(46378, 87536), tuple(35324, 26075), tuple(6310, 76915), tuple(1551, 69473), tuple(50642, 68865), tuple(55190, 72934), tuple(49780, 21873), tuple(99466, 29686), tuple(90761, 13179), tuple(72959, 57033), tuple(20020, 90200), tuple(46186, 79105), tuple(73871, 52382), tuple(59559, 38801), tuple(59916, 16082), tuple(33610, 94966), tuple(46001, 45225), tuple(86679, 26469), tuple(77245, 91929), tuple(32887, 36623), tuple(11179, 46898), tuple(87881, 68087), tuple(45438, 47991), tuple(24950, 94525), tuple(91664, 51656), tuple(43914, 47805), tuple(15736, 96156), tuple(56346, 20283), tuple(85053, 48931), tuple(17790, 26179), tuple(96195, 55728), tuple(43765, 54807), tuple(44988, 89269), tuple(55911, 99411), tuple(52446, 47397), tuple(28346, 65442), tuple(96669, 68226), tuple(66194, 26848), tuple(37276, 55864), tuple(14116, 41583), tuple(18058, 16317), tuple(93136, 85318), tuple(35616, 86252), tuple(29222, 29969), tuple(33386, 85372), tuple(71094, 44238), tuple(27733, 31838), tuple(64626, 16692), tuple(52904, 97899), tuple(97619, 12663), tuple(50165, 4688), tuple(67557, 44053), tuple(69184, 66269), tuple(73164, 89705), tuple(39822, 15169), tuple(65499, 72808), tuple(30068, 63697), tuple(30154, 64235), tuple(97016, 58716), tuple(94366, 36592), tuple(1592, 16261), tuple(87985, 52102), tuple(12554, 23652), tuple(15909, 25292), tuple(2527, 91531), tuple(92139, 36031), tuple(28986, 30032), tuple(3038, 56314), tuple(32239, 26707), tuple(15973, 34901), tuple(70246, 39680), tuple(82529, 38132), tuple(45827, 74783), tuple(53665, 64111), tuple(55218, 84170), tuple(20466, 16130), tuple(55734, 71203), tuple(31438, 96906), tuple(66338, 85858), tuple(35988, 68511), tuple(78391, 15191), tuple(80747, 59213), tuple(5357, 11546), tuple(16822, 16607), tuple(36607, 41106), tuple(74949, 30739), tuple(45726, 64887), tuple(1524, 54847), tuple(37371, 89195), tuple(28726, 27788), tuple(22600, 44777), tuple(53999, 63625), tuple(84304, 98338), tuple(49260, 76480), tuple(74564, 53907), tuple(89867, 97096), tuple(60157, 61299), tuple(17165, 10146), tuple(56334, 36268), tuple(62114, 49222), tuple(22715, 23620), tuple(42830, 11539), tuple(41091, 69151), tuple(75471, 68364), tuple(18681, 43249), tuple(42738, 63219), tuple(35474, 98454), tuple(76815, 46024), tuple(66310, 36521), tuple(86095, 77013), tuple(63693, 77319), tuple(80731, 63031), tuple(95478, 92387), tuple(23787, 63724), tuple(46299, 68994), tuple(4800, 2460), tuple(9663, 80639), tuple(77231, 85814), tuple(81615, 11311), tuple(35638, 27340), tuple(13598, 14322), tuple(30657, 17238), tuple(90957, 96846), tuple(69962, 52140), tuple(41681, 65962), tuple(96836, 58177), tuple(36190, 11623), tuple(4231, 40500), tuple(43049, 41949), tuple(71177, 98492), tuple(30193, 39750), tuple(19744, 33204), tuple(63358, 30210), tuple(45638, 58918), tuple(43641, 38741), tuple(35598, 40932), tuple(33238, 36236), tuple(50835, 20968), tuple(25099, 34071), tuple(84986, 88456), tuple(35333, 1529), tuple(79771, 23985), tuple(647, 61658), tuple(9424, 11743), tuple(77766, 31528), tuple(77811, 86973), tuple(76403, 74377), tuple(55568, 79251), tuple(68858, 20762), tuple(68520, 66773), tuple(93598, 89823), tuple(8080, 82539), tuple(87760, 52247), tuple(25191, 16905), tuple(17837, 8339), tuple(85177, 59050), tuple(51680, 77374), tuple(3287, 43018), tuple(43479, 62141), tuple(34909, 46322), tuple(11869, 5885), tuple(96193, 58417), tuple(101, 47460), tuple(34937, 88582), tuple(83216, 88388), tuple(28571, 15292), tuple(66683, 62613), tuple(34478, 8924), tuple(2680, 89973), tuple(62438, 44460), tuple(11724, 4791), tuple(5383, 72888), tuple(88206, 67586), tuple(8124, 21690), tuple(28779, 75789), tuple(66791, 4757), tuple(6176, 47760), tuple(6403, 78084), tuple(78122, 35446), tuple(99494, 73608), tuple(39691, 89098), tuple(59182, 19484), tuple(25389, 98963), tuple(96487, 3692), tuple(76222, 67381), tuple(21199, 50358), tuple(95998, 58137), tuple(28777, 43913), tuple(14176, 60117), tuple(52257, 81703), tuple(14604, 13438), tuple(71301, 14401), tuple(19758, 66914), tuple(15506, 29873), tuple(87205, 29449), tuple(93295, 15930), tuple(63651, 11287), tuple(19785, 15966), tuple(30795, 75112), tuple(69462, 37655), tuple(18793, 85764), tuple(36240, 31236), tuple(98153, 73724), tuple(72491, 4223), tuple(66930, 35048), tuple(25686, 13269), tuple(13940, 13259), tuple(69163, 11235), tuple(1183, 86961), tuple(54323, 67315), tuple(85044, 60872), tuple(48875, 3683), tuple(43052, 92861), tuple(87574, 32969), tuple(92552, 80564), tuple(94832, 47682), tuple(72011, 80994), tuple(60182, 917), tuple(97788, 34169), tuple(66432, 47940), tuple(87468, 80954), tuple(35385, 68758), tuple(50555, 63710), tuple(55311, 44337), tuple(87065, 26514), tuple(84581, 98736), tuple(23212, 56499), tuple(75120, 72447), tuple(56087, 38285), tuple(58171, 45629), tuple(28401, 44319), tuple(70432, 27883), tuple(18891, 14646), tuple(26206, 49924), tuple(79957, 44914), tuple(56064, 27529), tuple(99090, 29197), tuple(49435, 340), tuple(53525, 65601), tuple(76998, 88349), tuple(50416, 70860), tuple(42506, 75290), tuple(34024, 13295), tuple(86663, 46523), tuple(88814, 231), tuple(57809, 21), tuple(84914, 84771), tuple(43042, 66892), tuple(17288, 33908), tuple(4934, 63195), tuple(50590, 1516), tuple(97843, 80208), tuple(20091, 86717), tuple(71566, 15929), tuple(19531, 23634), tuple(41646, 45549), tuple(89226, 82902), tuple(96683, 63386), tuple(31072, 53788), tuple(51135, 41099), tuple(78912, 65609), tuple(36094, 23603), tuple(88403, 51455), tuple(73795, 47066), tuple(26448, 82852), tuple(22829, 2894), tuple(30041, 92548), tuple(27733, 20608), tuple(70180, 19892), tuple(51650, 63440), tuple(76328, 13666), tuple(40514, 6677), tuple(2786, 51059), tuple(40809, 16499), tuple(10857, 82541), tuple(78221, 61067), tuple(17982, 51969), tuple(85369, 66965), tuple(47153, 47149), tuple(43965, 75796), tuple(82725, 60767), tuple(42407, 97249), tuple(51475, 81224), tuple(60957, 89414), tuple(33065, 21663), tuple(36601, 5290), tuple(95842, 67301), tuple(64630, 60398), tuple(55212, 35638), tuple(41750, 44235), tuple(75260, 82400), tuple(91291, 25843), tuple(6477, 8311), tuple(14919, 52306), tuple(66220, 33180), tuple(45736, 2313), tuple(37450, 64444), tuple(98614, 61344), tuple(75007, 50946), tuple(56701, 28117), tuple(66632, 5174), tuple(92323, 76613), tuple(6796, 73695), tuple(33696, 76280), tuple(86876, 5614), tuple(50863, 67993), tuple(36068, 17049), tuple(91912, 34271), tuple(70706, 1904), tuple(97798, 41117), tuple(68154, 72483), tuple(83862, 25578), tuple(61643, 17204), tuple(69974, 64232), tuple(77926, 19637), + tuple(64901, 88988), tuple(71424, 91703), tuple(91655, 17147), tuple(46872, 56530), tuple(44189, 98087), tuple(95939, 54420), tuple(72651, 68785), tuple(67624, 84875), tuple(92587, 87663), tuple(65275, 81256), tuple(53798, 2506), tuple(14702, 3638), tuple(71291, 50452), tuple(14909, 13903), tuple(66965, 26606), tuple(14127, 60345), tuple(35306, 1738), tuple(77234, 10468), tuple(53521, 41218), tuple(80681, 82583), tuple(44227, 26521), tuple(32263, 21482), tuple(82270, 56963), tuple(50580, 80567), tuple(11593, 22346), tuple(20074, 26867), tuple(73126, 28667), tuple(62996, 24317), tuple(20295, 57163), tuple(1506, 57668), tuple(69567, 45236), tuple(43366, 26001), tuple(88052, 40181), tuple(1599, 89349), tuple(36789, 1579), tuple(39895, 46673), tuple(30381, 3206), tuple(31723, 5625), tuple(19252, 31317), tuple(16932, 77149), tuple(48794, 34409), tuple(55986, 30328), tuple(47551, 75088), tuple(57363, 78365), tuple(95221, 63385), tuple(26449, 5733), tuple(96588, 53077), tuple(52980, 41140), tuple(8187, 85947), tuple(36723, 26520), tuple(23579, 38909), tuple(33350, 19275), tuple(63930, 19357), tuple(43536, 59941), tuple(31117, 77322), tuple(44638, 94812), tuple(44730, 99097), tuple(95108, 48170), tuple(57813, 49503), tuple(79959, 89436), tuple(86980, 62031), tuple(8275, 44009), tuple(36666, 94645), tuple(22064, 38882), tuple(40471, 16939), tuple(31156, 11337), tuple(13101, 96977), tuple(17906, 26835), tuple(89861, 51405), tuple(73369, 67946), tuple(99141, 58572), tuple(27131, 98703), tuple(15900, 43412), tuple(51768, 93125), tuple(78579, 46689), tuple(23029, 13895), tuple(60870, 55830), tuple(22553, 8236), tuple(76449, 96207), tuple(83766, 51024), tuple(27630, 50614), tuple(53484, 90104), tuple(77626, 21944), tuple(46755, 41583), tuple(53616, 34240), tuple(94159, 44415), tuple(13914, 90059), tuple(44387, 89012), tuple(27499, 64579), tuple(83415, 30809), tuple(77558, 82619), tuple(88880, 9814), tuple(8466, 4424), tuple(43598, 91921), tuple(24695, 3349), tuple(46295, 65208), tuple(51256, 82461), tuple(49126, 93012), tuple(16186, 96585), tuple(43284, 22655), tuple(93130, 90393), tuple(77495, 34372), tuple(85509, 65856), tuple(86662, 61906), tuple(50988, 44393), tuple(29828, 17737), tuple(91651, 35308), tuple(29796, 49716), tuple(14019, 87751), tuple(29688, 71207), tuple(82845, 19100), tuple(11989, 50132), tuple(21158, 99905), tuple(54732, 42547), tuple(32314, 12851), tuple(46405, 43794), tuple(87849, 45643), tuple(53524, 21212), tuple(61925, 75491), tuple(12498, 21937), tuple(30185, 69475), tuple(48421, 52487), tuple(15112, 90935), tuple(33187, 17801), tuple(61704, 25514), tuple(17889, 23917), tuple(18758, 57197), tuple(7693, 47232), tuple(47905, 24618), tuple(11494, 78950), tuple(95662, 54561), tuple(8075, 33909), tuple(90427, 46065), tuple(73962, 19821), tuple(50691, 79400), tuple(58218, 4881), tuple(94106, 2509), tuple(60633, 55169), tuple(49600, 83054), tuple(23339, 13270), tuple(70262, 58946), tuple(48417, 97266), tuple(27629, 46905), tuple(74465, 75514), tuple(41687, 2564), tuple(12814, 19492), tuple(78899, 30168), tuple(17745, 35206), tuple(37972, 35296), tuple(22288, 80001), tuple(68026, 36558), tuple(40187, 12234), tuple(92380, 22866), tuple(56488, 64402), tuple(41404, 62562), tuple(47802, 45287), tuple(83302, 85215), tuple(58999, 85776), tuple(35158, 16804), tuple(13416, 94146), tuple(62953, 28243), tuple(83290, 19103), tuple(4564, 21789), tuple(64468, 20927), tuple(25582, 47206), tuple(57810, 18693), tuple(28938, 97986), tuple(61704, 14838), tuple(19214, 3232), tuple(12911, 25438), tuple(85802, 28837), tuple(56506, 89458), tuple(66392, 47773), tuple(68190, 43841), tuple(43044, 52214), tuple(57886, 32830), tuple(15943, 59771), tuple(37081, 89294), tuple(4032, 32960), tuple(46931, 85790), tuple(69656, 72737), tuple(28217, 39872), tuple(86170, 42776), tuple(55116, 51495), tuple(90485, 45274), tuple(60773, 36788), tuple(2193, 2636), tuple(70222, 62086), tuple(75720, 70712), tuple(17549, 51460), tuple(23609, 31515), tuple(70254, 39825), tuple(63762, 11061), tuple(13107, 15394), tuple(45916, 72130), tuple(91558, 86662), tuple(99524, 69106), tuple(93073, 29881), tuple(31724, 3007), tuple(69051, 59452), tuple(59701, 86760), tuple(4967, 82028), tuple(57404, 48226), tuple(71829, 79910), tuple(23714, 62439), tuple(73881, 67618), tuple(63269, 40085), tuple(6164, 23415), tuple(48156, 93907), tuple(18627, 16570), tuple(6676, 22991), tuple(36916, 41488), tuple(99079, 13264), tuple(32533, 99243), tuple(55505, 63339), tuple(89564, 3290), tuple(24886, 34916), tuple(91310, 9343), tuple(49779, 12740), tuple(26320, 3406), tuple(57661, 5702), tuple(10765, 57881), tuple(5518, 47638), tuple(93148, 27438), tuple(73451, 24477), tuple(84075, 96822), tuple(58883, 58883), tuple(96812, 82388), tuple(30659, 59654), tuple(24498, 95808), tuple(25591, 21834), tuple(13090, 87704), tuple(76495, 17249), tuple(75975, 84318), tuple(55459, 70426), tuple(84256, 88604), tuple(79438, 43104), tuple(45331, 7495), tuple(63619, 11123), tuple(24772, 2601), tuple(63343, 14138), tuple(39957, 98339), tuple(55595, 17823), tuple(97676, 53933), tuple(91867, 25023), tuple(64677, 67859), tuple(43737, 34315), tuple(24800, 53968), tuple(93157, 17507), tuple(24264, 35273), tuple(33889, 507), tuple(10207, 40542), tuple(40213, 57800), tuple(38321, 74160), tuple(42391, 7651), tuple(80267, 94736), tuple(52473, 79634), tuple(17075, 2531), tuple(8595, 75890), tuple(31496, 50367), tuple(16069, 79896), tuple(70067, 200), tuple(23420, 49517), tuple(1628, 45646), tuple(8916, 36794), tuple(72294, 88976), tuple(40603, 86008), tuple(91871, 71098), tuple(5447, 70998), tuple(24152, 17561), tuple(65046, 34951), tuple(56950, 9292), tuple(19244, 31385), tuple(74693, 31813), tuple(97343, 21572), tuple(38834, 135), tuple(79717, 62486), tuple(38, 10308), tuple(58035, 71344), tuple(85802, 81079), tuple(5943, 156), tuple(38735, 38867), tuple(3803, 99366), tuple(15853, 19408), tuple(62988, 62008), tuple(8316, 44684), tuple(17035, 71012), tuple(48584, 2117), tuple(75425, 37336), tuple(2405, 50420), tuple(43653, 28836), tuple(12394, 69430), tuple(54522, 4954), tuple(33359, 148), tuple(41018, 82851), tuple(79995, 55417), tuple(65008, 32342), tuple(36547, 88185), tuple(8131, 7054), tuple(38980, 20146), tuple(27976, 63039), tuple(53119, 67009), tuple(40043, 98393), tuple(29333, 51980), tuple(85818, 98405), tuple(77956, 20099), tuple(99747, 16916), tuple(11597, 50181), tuple(40961, 8262), tuple(75103, 13912), tuple(62339, 69155), tuple(3869, 85481), tuple(7053, 30956), tuple(33563, 53272), tuple(96178, 81751), tuple(99365, 88728), tuple(34447, 11164), tuple(62856, 30939), tuple(92486, 3357), tuple(56605, 35330), tuple(42180, 15137), tuple(83946, 62984), tuple(61869, 55711), tuple(52880, 49871), tuple(44588, 27387), tuple(16332, 24496), tuple(1781, 13508), tuple(56674, 95773), tuple(21328, 19628), tuple(96455, 24155), tuple(14302, 74435), tuple(54053, 24590), tuple(86642, 22177), tuple(24089, 16186), tuple(70281, 4601), tuple(18552, 70708), tuple(95442, 5895), tuple(96714, 6293), tuple(43803, 45857), tuple(93257, 18497), tuple(90032, 85086), tuple(40566, 87233), tuple(32674, 73822), tuple(95599, 49334), tuple(62745, 51898), tuple(8245, 93882), tuple(14093, 40977), tuple(47215, 53001), tuple(59737, 68452), tuple(90937, 25354), tuple(43805, 82571), tuple(81953, 68572), tuple(37298, 96262), tuple(94899, 65066), tuple(34772, 80762), tuple(55469, 1186), tuple(8734, 91665), tuple(18622, 51150), tuple(85200, 39575), tuple(65381, 15979), tuple(89734, 89656), tuple(64712, 53691), tuple(87187, 58256), tuple(8476, 89694), tuple(49935, 35239), tuple(63730, 34982), tuple(27687, 91571), tuple(87543, 15350), tuple(85208, 18781), tuple(14783, 2574), tuple(44699, 666), tuple(56440, 87617), tuple(32732, 49301), tuple(76725, 3895), tuple(10419, 90580), tuple(34725, 69476), tuple(14831, 81588), tuple(93924, 38057), tuple(38528, 99060), tuple(57136, 44206), tuple(74685, 99559), tuple(43083, 87511), tuple(43105, 35474), tuple(35582, 17560), tuple(5578, 98727), tuple(78947, 53865), tuple(32013, 95029), tuple(61552, 42674), tuple(52191, 49975), tuple(71566, 16403), tuple(78534, 16350), tuple(18520, 80501), tuple(29114, 46547), tuple(11488, 5069), tuple(89591, 82384), tuple(13741, 42318), tuple(74385, 58849), tuple(49739, 63421), tuple(83821, 6676), tuple(51997, 93321), tuple(36677, 81768), tuple(37915, 73495), tuple(47175, 6086), tuple(39989, 83110), tuple(6489, 48112), tuple(88822, 20370), tuple(12846, 13952), tuple(28930, 20879), tuple(25139, 84552), tuple(76434, 2665), tuple(55145, 31523), tuple(21177, 18630), tuple(81077, 96275), tuple(61006, 30845), tuple(77722, 62651), tuple(61181, 72545), tuple(93838, 84287), tuple(59300, 19014), tuple(75076, 97980), tuple(76979, 1473), tuple(48409, 13097), tuple(51718, 5325), tuple(36522, 72119), tuple(60917, 18995), tuple(61469, 42853), tuple(34387, 37322), tuple(38684, 28120), tuple(64136, 8559), tuple(15368, 99424), tuple(97824, 7864), tuple(33833, 72029), tuple(7024, 9961), tuple(49400, 66220), tuple(63025, 97179), tuple(6135, 98878), tuple(19873, 8438), tuple(3963, 35670), tuple(65186, 89423), tuple(26653, 65943), tuple(83132, 67000), tuple(82578, 35007), tuple(42680, 60479), tuple(71102, 98589), tuple(74842, 94010), tuple(22931, 33725), tuple(46537, 42629), tuple(75793, 48115), tuple(21630, 92454), tuple(97993, 81332), tuple(25747, 31814), tuple(91231, 65953), tuple(91981, 12219), tuple(64719, 16254), tuple(60914, 8334), tuple(15887, 96432), tuple(42110, 28837), tuple(7295, 83147), tuple(50334, 7053), tuple(3949, 33594), tuple(1524, 98230), tuple(17265, 98024), tuple(75969, 36232), tuple(89538, 5212), tuple(13444, 55946), tuple(69823, 81848), tuple(32578, 74024), tuple(52018, 98290), tuple(59118, 40186), tuple(61002, 16977), tuple(69537, 44780), tuple(92, 13937), tuple(33715, 42663), tuple(46347, 8312), tuple(86196, 59301), tuple(17128, 85014), tuple(26429, 57682), tuple(45888, 99588), tuple(22750, 96110), tuple(46809, 49251), tuple(24521, 40071), tuple(287, 22115), + tuple(11741, 36315), tuple(22742, 17581), tuple(35808, 3110), tuple(98904, 30407), tuple(4584, 13383), tuple(28585, 69669), tuple(94823, 29715), tuple(9551, 36389), tuple(77997, 45746), tuple(49894, 55722), tuple(23415, 69459), tuple(58246, 85144), tuple(74136, 18102), tuple(97366, 85724), tuple(34271, 51601), tuple(47535, 70883), tuple(59443, 90103), tuple(45213, 45811), tuple(62741, 86898), tuple(17324, 50034), tuple(62080, 25193), tuple(89524, 4421), tuple(13476, 51456), tuple(69198, 56718), tuple(58024, 22969), tuple(65210, 67941), tuple(32561, 44881), tuple(62295, 67448), tuple(66135, 95453), tuple(9417, 20443), tuple(82486, 23745), tuple(19185, 99041), tuple(40662, 91714), tuple(3423, 58624), tuple(4512, 74502), tuple(67772, 98023), tuple(69575, 75779), tuple(69107, 62805), tuple(517, 33801), tuple(47406, 7581), tuple(81108, 10546), tuple(12976, 47001), tuple(16742, 83811), tuple(44593, 82124), tuple(52731, 34642), tuple(81725, 20555), tuple(94126, 91919), tuple(24800, 59302), tuple(97253, 39249), tuple(71692, 10769), tuple(88721, 56321), tuple(7019, 69771), tuple(31464, 61774), tuple(29597, 19263), tuple(65557, 31875), tuple(28653, 69636), tuple(58074, 76848), tuple(15906, 80620), tuple(18259, 40193), tuple(99991, 4769), tuple(98935, 99269), tuple(12123, 60124), tuple(20787, 47346), tuple(13526, 33592), tuple(95370, 40350), tuple(17479, 42884), tuple(58368, 83218), tuple(63290, 74406), tuple(97030, 35102), tuple(45298, 27660), tuple(64593, 21262), tuple(76268, 82641), tuple(1107, 44044), tuple(21427, 79959), tuple(85180, 62412), tuple(7359, 1318), tuple(83618, 9762), tuple(1425, 55804), tuple(32874, 97943), tuple(68191, 38742), tuple(41715, 17902), tuple(3771, 15032), tuple(7848, 74950), tuple(33881, 40904), tuple(75295, 26151), tuple(75775, 13760), tuple(90262, 89822), tuple(88169, 18679), tuple(57506, 32356), tuple(94983, 44281), tuple(37385, 37432), tuple(18248, 48162), tuple(45573, 66278), tuple(25277, 72788), tuple(26977, 36778), tuple(26254, 61758), tuple(12860, 48026), tuple(96819, 3339), tuple(13134, 1173), tuple(26822, 53374), tuple(15989, 29698), tuple(11258, 54515), tuple(37866, 34928), tuple(22996, 26577), tuple(39952, 42732), tuple(6754, 70595), tuple(86245, 44669), tuple(47044, 34170), tuple(6789, 45220), tuple(31706, 2090), tuple(42582, 40023), tuple(35147, 46591), tuple(88210, 11307), tuple(53644, 7680), tuple(11280, 91075), tuple(42961, 65122), tuple(40066, 52185), tuple(20050, 6154), tuple(98440, 20393), tuple(88992, 75432), tuple(32386, 66731), tuple(36952, 34149), tuple(18453, 32715), tuple(84413, 10378), tuple(59440, 2374), tuple(45354, 85009), tuple(50382, 66510), tuple(64428, 95401), tuple(9336, 41760), tuple(26317, 91416), tuple(81941, 99504), tuple(26600, 53522), tuple(81069, 40236), tuple(51126, 27911), tuple(97144, 14243), tuple(62738, 50287), tuple(37372, 28962), tuple(12053, 9090), tuple(69492, 95524), tuple(68141, 52931), tuple(17276, 16487), tuple(69227, 25949), tuple(14143, 70193), tuple(7077, 53032), tuple(65463, 74082), tuple(94997, 66496), tuple(80443, 55832), tuple(66796, 5970), tuple(15852, 95662), tuple(81559, 97272), tuple(55851, 18977), tuple(91142, 48976), tuple(91143, 950), tuple(79225, 31004), tuple(61310, 20760), tuple(74541, 90842), tuple(80322, 11630), tuple(84631, 544), tuple(66785, 86591), tuple(25650, 63252), tuple(59635, 18586), tuple(2964, 6741), tuple(37091, 71148), tuple(11984, 43077), tuple(87505, 62049), tuple(61925, 92290), tuple(18808, 3937), tuple(8300, 33268), tuple(70850, 50661), tuple(86024, 73730), tuple(85161, 47116), tuple(50193, 89155), tuple(37773, 40845), tuple(9251, 41688), tuple(6940, 65399), tuple(42479, 95630), tuple(19401, 43102), tuple(48069, 36040), tuple(62760, 95013), tuple(394, 2641), tuple(32567, 29306), tuple(13870, 58835), tuple(98248, 47291), tuple(49803, 4523), tuple(40222, 12883), tuple(53576, 73105), tuple(88265, 23629), tuple(67865, 67875), tuple(33473, 27144), tuple(80219, 53893), tuple(74878, 47341), tuple(78070, 84803), tuple(30003, 5600), tuple(41103, 6145), tuple(83490, 81076), tuple(55059, 66736), tuple(45015, 10239), tuple(79555, 85819), tuple(81808, 34970), tuple(19235, 85480), tuple(91807, 52177), tuple(40887, 87009), tuple(5003, 2687), tuple(64964, 88122), tuple(765, 94893), tuple(93573, 20504), tuple(28854, 38438), tuple(94244, 93475), tuple(72996, 84801), tuple(75427, 81692), tuple(63161, 98637), tuple(18814, 61343), tuple(22863, 60110), tuple(8949, 12694), tuple(19675, 94313), tuple(43857, 74073), tuple(15737, 58218), tuple(48895, 68474), tuple(22220, 92926), tuple(69055, 50282), tuple(40532, 74934), tuple(59062, 66405), tuple(85784, 87704), tuple(58494, 88222), tuple(2260, 20401), tuple(73112, 99666), tuple(46739, 95433), tuple(21179, 85119), tuple(11545, 38801), tuple(59993, 50866), tuple(10086, 4709), tuple(70560, 29611), tuple(27095, 89017), tuple(6896, 2279), tuple(92506, 5013), tuple(48600, 90491), tuple(18782, 54638), tuple(54337, 82734), tuple(52054, 13481), tuple(38297, 56559), tuple(15998, 30591), tuple(89789, 7522), tuple(18149, 28725), tuple(3532, 28625), tuple(70934, 49617), tuple(84599, 55664), tuple(74229, 52269), tuple(55431, 11893), tuple(32807, 72543), tuple(83882, 53025), tuple(11490, 83442), tuple(14844, 88612), tuple(12526, 45953), tuple(906, 2231), tuple(68240, 95612), tuple(18818, 31535), tuple(57774, 91290), tuple(67250, 67400), tuple(77332, 23550), tuple(42332, 57775), tuple(28792, 11539), tuple(19108, 34608), tuple(12399, 38591), tuple(7329, 10740), tuple(84288, 50928), tuple(29461, 17629), tuple(63884, 88489), tuple(47479, 61085), tuple(75357, 57255), tuple(60107, 94046), tuple(32934, 66312), tuple(28615, 42600), tuple(55553, 85213), tuple(57838, 91426), tuple(9783, 11513), tuple(73677, 28821), tuple(75408, 75561), tuple(22995, 59224), tuple(74874, 54145), tuple(18513, 75901), tuple(46440, 69414), tuple(36072, 22263), tuple(60560, 73325), tuple(69967, 93358), tuple(75949, 98634), tuple(3688, 57991), tuple(43482, 94541), tuple(40922, 31011), tuple(57763, 74497), tuple(93576, 96392), tuple(83038, 80656), tuple(47757, 87045), tuple(14061, 53465), tuple(65619, 33775), tuple(11341, 6702), tuple(6249, 87358), tuple(15766, 85937), tuple(13135, 93945), tuple(24495, 95900), tuple(80359, 1739), tuple(15468, 73426), tuple(49240, 44999), tuple(82839, 90808), tuple(87438, 75613), tuple(348, 73144), tuple(99523, 85853), tuple(21557, 70210), tuple(64933, 1672), tuple(38154, 17477), tuple(97136, 67363), tuple(96491, 8038), tuple(97981, 3434), tuple(54372, 27038), tuple(88480, 86675), tuple(21028, 21083), tuple(43197, 4440), tuple(31702, 78290), tuple(66631, 24438), tuple(11482, 17922), tuple(90351, 39503), tuple(46186, 32439), tuple(73828, 6640), tuple(56916, 26029), tuple(62840, 1815), tuple(20281, 28488), tuple(18211, 30043), tuple(65211, 93012), tuple(43614, 58012), tuple(90322, 77343), tuple(64293, 94525), tuple(59489, 39760), tuple(93219, 78440), tuple(74613, 9732), tuple(38085, 19191), tuple(58029, 48186), tuple(88762, 1764), tuple(28627, 21993), tuple(49975, 41225), tuple(70486, 43480), tuple(82764, 96425), tuple(27218, 78327), tuple(17844, 73333), tuple(70463, 37629), tuple(10500, 33826), tuple(97343, 66575), tuple(82833, 51210), tuple(77353, 45073), tuple(27163, 39728), tuple(78076, 46691), tuple(80302, 39342), tuple(77142, 1319), tuple(87403, 80110), tuple(53805, 27786), tuple(50558, 74264), tuple(83146, 31358), tuple(11567, 4438), tuple(30041, 54287), tuple(91731, 18496), tuple(57591, 93894), tuple(72534, 59009), tuple(98064, 59148), tuple(69626, 66615), tuple(20951, 43949), tuple(61960, 68060), tuple(48892, 67918), tuple(61321, 56222), tuple(75424, 77260), tuple(4916, 81929), tuple(68892, 81531), tuple(28096, 28548), tuple(62016, 107), tuple(8593, 12030), tuple(66743, 36772), tuple(60174, 15106), tuple(52844, 1923), tuple(34768, 22065), tuple(88988, 62910), tuple(79214, 2998), tuple(25675, 31376), tuple(69959, 3614), tuple(43885, 31708), tuple(12206, 46548), tuple(69924, 19343), tuple(12984, 38980), tuple(58250, 69438), tuple(2580, 48684), tuple(38112, 37124), tuple(21842, 43150), tuple(59384, 21921), tuple(19908, 46678), tuple(73396, 79529), tuple(8274, 1557), tuple(36975, 65519), tuple(81069, 18712), tuple(13692, 9148), tuple(60617, 84762), tuple(75749, 66154), tuple(80375, 24553), tuple(4257, 47056), tuple(76880, 7687), tuple(40714, 43448), tuple(79112, 74791), tuple(33119, 72730), tuple(17670, 89183), tuple(51614, 3921), tuple(21247, 39857), tuple(86756, 67673), tuple(32792, 70035), tuple(5917, 7197), tuple(1762, 23130), tuple(6455, 63664), tuple(32806, 3729), tuple(60469, 20511), tuple(12522, 15149), tuple(98106, 79338), tuple(84754, 11162), tuple(52058, 17973), tuple(28789, 1521), tuple(32766, 36325), tuple(78914, 40453), tuple(70297, 71854), tuple(9313, 45190), tuple(54559, 66227), tuple(22342, 43860), tuple(44152, 84294), tuple(36913, 93173), tuple(88523, 36338), tuple(82234, 71140), tuple(8328, 22947), tuple(73250, 88125), tuple(74356, 16820), tuple(94472, 37349), tuple(23126, 87806), tuple(40315, 88729), tuple(19935, 19145), tuple(93312, 65719), tuple(8477, 33108), tuple(86660, 69525), tuple(75557, 66964), tuple(60437, 57494), tuple(94419, 42524), tuple(95372, 72274), tuple(49866, 85685), tuple(96808, 39404), tuple(62961, 72507), tuple(38634, 70815), tuple(91379, 42430), tuple(66359, 98699), tuple(24382, 4186), tuple(4003, 77760), tuple(87840, 75265), tuple(57641, 68871), tuple(9773, 15942), tuple(5664, 51289), tuple(47923, 31308), tuple(58632, 82468), tuple(14097, 71829), tuple(1838, 97710), tuple(70433, 11364), tuple(82363, 97879), tuple(25257, 20615), tuple(18249, 6758), tuple(98581, 13639), tuple(3290, 72449), tuple(74546, 79380), tuple(97254, 44448), tuple(80316, 31760), tuple(40516, 94809), tuple(14444, 88981), tuple(9693, 10259), tuple(83795, 95485), tuple(70201, 81014), tuple(66644, 16761), tuple(35529, 82718), tuple(75774, 73476), tuple(80139, 3957), tuple(34803, 80689), tuple(92085, 46499), tuple(97871, 8004), tuple(67369, 11354), tuple(43578, 81596), + tuple(94695, 44963), tuple(93741, 41629), tuple(16005, 96652), tuple(37918, 69012), tuple(89832, 56041), tuple(51798, 32386), tuple(89749, 27647), tuple(76279, 7990), tuple(31746, 1346), tuple(40841, 20480), tuple(99942, 24473), tuple(78495, 99194), tuple(13588, 57088), tuple(22183, 42297), tuple(82707, 34435), tuple(45026, 12747), tuple(8000, 93211), tuple(40453, 13025), tuple(44100, 39880), tuple(83900, 56474), tuple(87691, 42802), tuple(82000, 63867), tuple(76627, 84731), tuple(112, 92774), tuple(34749, 97737), tuple(59262, 57169), tuple(95571, 44144), tuple(74310, 68970), tuple(63232, 92744), tuple(53698, 21610), tuple(39969, 75475), tuple(39942, 28713), tuple(81230, 50140), tuple(97953, 96528), tuple(86144, 48041), tuple(96677, 49677), tuple(22051, 48183), tuple(33436, 54784), tuple(5553, 11920), tuple(67057, 17115), tuple(57736, 72309), tuple(8086, 85329), tuple(72623, 94949), tuple(13096, 48992), tuple(63153, 56337), tuple(30462, 1036), tuple(75000, 24048), tuple(62635, 50128), tuple(91480, 83131), tuple(25929, 79809), tuple(96237, 76974), tuple(59645, 20603), tuple(31850, 29754), tuple(91070, 36568), tuple(30191, 33785), tuple(86776, 67259), tuple(49073, 39179), tuple(16121, 73834), tuple(84217, 52951), tuple(95866, 47244), tuple(63326, 73460), tuple(134, 91953), tuple(48189, 86069), tuple(42971, 3700), tuple(28643, 10479), tuple(80151, 7446), tuple(78798, 2655), tuple(39135, 69364), tuple(80244, 24904), tuple(22818, 74964), tuple(26753, 82419), tuple(16858, 5212), tuple(79891, 11215), tuple(785, 46103), tuple(12559, 24617), tuple(73601, 71490), tuple(70342, 7099), tuple(73330, 6665), tuple(11903, 28194), tuple(16375, 37746), tuple(86132, 51788), tuple(90345, 68366), tuple(5464, 78338), tuple(23569, 83141), tuple(17904, 94046), tuple(35868, 60017), tuple(22591, 93373), tuple(70584, 72116), tuple(49331, 34312), tuple(16180, 91286), tuple(58494, 65441), tuple(9336, 52671), tuple(32523, 26734), tuple(40205, 83549), tuple(28810, 96876), tuple(44703, 38944), tuple(46981, 37157), tuple(8582, 7529), tuple(59718, 71700), tuple(62545, 73716), tuple(6531, 23200), tuple(30528, 59720), tuple(57152, 84660), tuple(16232, 67946), tuple(60446, 45983), tuple(68737, 54959), tuple(57795, 73107), tuple(26930, 35938), tuple(9844, 44760), tuple(3716, 79020), tuple(99126, 8264), tuple(66120, 16151), tuple(50616, 25765), tuple(93340, 95875), tuple(34103, 88003), tuple(14879, 99758), tuple(49188, 6087), tuple(89858, 42861), tuple(36730, 72076), tuple(25069, 26403), tuple(98183, 48108), tuple(3229, 5367), tuple(59306, 80078), tuple(61144, 58598), tuple(72600, 98765), tuple(57701, 23177), tuple(10176, 11553), tuple(82964, 13697), tuple(7788, 28538), tuple(39943, 97491), tuple(56261, 17781), tuple(2458, 1892), tuple(6679, 45554), tuple(42171, 66222), tuple(24420, 44115), tuple(35852, 41965), tuple(50196, 49555), tuple(34718, 60734), tuple(6932, 61638), tuple(69472, 56723), tuple(489, 97620), tuple(41335, 90578), tuple(1333, 92787), tuple(97883, 64754), tuple(14208, 22097), tuple(75776, 5938), tuple(67446, 61518), tuple(58743, 45162), tuple(34749, 81243), tuple(71451, 91991), tuple(27804, 41836), tuple(45274, 8039), tuple(17593, 24498), tuple(8801, 38559), tuple(87460, 7109), tuple(50075, 18284), tuple(84043, 82146), tuple(62932, 25018), tuple(89647, 56768), tuple(59920, 80801), tuple(56357, 35142), tuple(97376, 58181), tuple(70715, 91103), tuple(90829, 78985), tuple(29776, 13275), tuple(30546, 42320), tuple(99266, 35340), tuple(21234, 61062), tuple(39239, 10745), tuple(45990, 715), tuple(47047, 6619), tuple(4270, 94575), tuple(90009, 72203), tuple(25629, 2691), tuple(67926, 89112), tuple(46990, 61101), tuple(22355, 69536), tuple(1977, 56723), tuple(54681, 34041), tuple(83819, 7024), tuple(81235, 7093), tuple(16659, 87135), tuple(49384, 32135), tuple(42204, 17362), tuple(90585, 70374), tuple(51255, 1), tuple(31600, 70085), tuple(90189, 95778), tuple(57349, 87789), tuple(83384, 93771), tuple(20718, 15529), tuple(10644, 53591), tuple(84103, 62101), tuple(91340, 48382), tuple(82854, 84420), tuple(12561, 53517), tuple(64835, 45362), tuple(54154, 75841), tuple(46498, 31175), tuple(75035, 49552), tuple(9306, 53403), tuple(68851, 49139), tuple(13463, 42107), tuple(2322, 36695), tuple(55953, 12098), tuple(60656, 80482), tuple(78987, 19632), tuple(31228, 18523), tuple(98972, 80489), tuple(32367, 98405), tuple(25139, 5164), tuple(5692, 60610), tuple(36535, 70097), tuple(80542, 74320), tuple(87984, 46750), tuple(98201, 41341), tuple(35217, 46813), tuple(81795, 69057), tuple(83927, 41032), tuple(60149, 26087), tuple(39954, 48361), tuple(64485, 61448), tuple(87185, 14580), tuple(74559, 93251), tuple(88544, 83366), tuple(74015, 15864), tuple(78623, 69719), tuple(16941, 80710), tuple(16315, 58313), tuple(47277, 59107), tuple(16067, 66290), tuple(63906, 59891), tuple(20754, 67817), tuple(44428, 10652), tuple(95960, 99045), tuple(52163, 26221), tuple(65566, 22057), tuple(26836, 38898), tuple(57107, 79274), tuple(39020, 74857), tuple(53540, 84159), tuple(76646, 44324), tuple(27967, 40171), tuple(28710, 56332), tuple(84036, 28711), tuple(68742, 57241), tuple(40535, 34737), tuple(62681, 85386), tuple(30472, 58405), tuple(85086, 33013), tuple(67059, 47481), tuple(30441, 55098), tuple(97892, 71991), tuple(90296, 42905), tuple(22441, 18863), tuple(19606, 77242), tuple(11206, 58380), tuple(23901, 49962), tuple(84094, 33761), tuple(64400, 28093), tuple(64228, 94543), tuple(71874, 20871), tuple(25385, 73117), tuple(63398, 20999), tuple(77547, 51893), tuple(80783, 65858), tuple(39807, 80754), tuple(10336, 90318), tuple(7826, 55346), tuple(30206, 10711), tuple(94411, 67364), tuple(33509, 14329), tuple(65350, 17006), tuple(65999, 55699), tuple(82753, 61081), tuple(38851, 11896), tuple(15155, 48635), tuple(19985, 75204), tuple(37144, 5344), tuple(26173, 39587), tuple(61111, 30966), tuple(16180, 22987), tuple(60707, 43599), tuple(30136, 74118), tuple(7880, 43857), tuple(97445, 30233), tuple(62700, 24828), tuple(90914, 89452), tuple(64131, 56925), tuple(25259, 39132), tuple(47104, 43950), tuple(93891, 21913), tuple(84573, 91029), tuple(8604, 79858), tuple(33141, 25534), tuple(12468, 90413), tuple(97063, 76359), tuple(80826, 26061), tuple(64013, 99099), tuple(82158, 38882), tuple(25799, 7564), tuple(25477, 69847), tuple(73374, 58520), tuple(48230, 9453), tuple(91424, 72273), tuple(64893, 11750), tuple(46753, 48434), tuple(15974, 94633), tuple(14872, 27027), tuple(14527, 21313), tuple(25660, 64644), tuple(54196, 15138), tuple(6313, 10911), tuple(36168, 47170), tuple(45346, 76), tuple(10305, 60286), tuple(65283, 39977), tuple(21804, 37972), tuple(65389, 86954), tuple(90674, 64458), tuple(15838, 22392), tuple(43540, 42503), tuple(49584, 67828), tuple(56711, 87887), tuple(40075, 73696), tuple(23832, 91552), tuple(39002, 65562), tuple(20451, 64664), tuple(70783, 92171), tuple(29319, 57694), tuple(56217, 44247), tuple(52856, 57873), tuple(80560, 90902), tuple(31068, 11280), tuple(46996, 34739), tuple(57527, 4554), tuple(8410, 25816), tuple(12269, 38319), tuple(88054, 49939), tuple(337, 13231), tuple(56432, 68236), tuple(74841, 21476), tuple(96006, 15712), tuple(87145, 91660), tuple(58090, 55111), tuple(10310, 79789), tuple(5734, 79710), tuple(98992, 69026), tuple(77033, 5734), tuple(43338, 42635), tuple(23898, 28669), tuple(62708, 81652), tuple(41279, 51722), tuple(93444, 26355), tuple(62046, 52199), tuple(71492, 58736), tuple(7379, 62581), tuple(8592, 71885), tuple(75026, 40387), tuple(46696, 3939), tuple(9787, 88907), tuple(86356, 363), tuple(97479, 20358), tuple(77363, 65553), tuple(44036, 22178), tuple(98279, 64612), tuple(3615, 411), tuple(77003, 93018), tuple(41605, 88489), tuple(55992, 83614), tuple(19493, 21633), tuple(34639, 97064), tuple(94602, 89289), tuple(45853, 26299), tuple(84170, 73386), tuple(9221, 51439), tuple(41513, 68166), tuple(37170, 17690), tuple(82511, 59246), tuple(96674, 27574), tuple(99301, 45675), tuple(42716, 41520), tuple(56623, 49130), tuple(84100, 76804), tuple(73855, 97007), tuple(73303, 26912), tuple(37151, 23837), tuple(49190, 97104), tuple(23487, 45628), tuple(87763, 46550), tuple(65111, 92605), tuple(80481, 8151), tuple(83949, 18930), tuple(81749, 27244), tuple(37449, 3023), tuple(28303, 51545), tuple(96441, 93242), tuple(22082, 43254), tuple(35135, 68407), tuple(37712, 48709), tuple(5111, 26774), tuple(15532, 74246), tuple(93605, 83583), tuple(21491, 66472), tuple(38922, 53076), tuple(55455, 54432), tuple(955, 44063), tuple(311, 91630), tuple(53554, 4522), tuple(29927, 65668), tuple(7525, 16035), tuple(44093, 76745), tuple(21481, 78198), tuple(76875, 5306), tuple(56126, 76437), tuple(96534, 16880), tuple(85600, 68336), tuple(4479, 81002), tuple(80414, 11593), tuple(8186, 61147), tuple(5624, 32879), tuple(79312, 20995), tuple(40407, 41512), tuple(91261, 66022), tuple(93228, 75364), tuple(21136, 40111), tuple(92148, 60681), tuple(42549, 7944), tuple(60157, 15040), tuple(63562, 88365), tuple(69056, 72713), tuple(78263, 89223), tuple(3776, 33039), tuple(30042, 59984), tuple(64567, 20977), tuple(24720, 39157), tuple(63582, 75653), tuple(45363, 20249), tuple(58093, 53833), tuple(27918, 93306), tuple(25791, 92686), tuple(15904, 862), tuple(72093, 19257), tuple(64125, 88986), tuple(41717, 27989), tuple(43165, 98675), tuple(76840, 48170), tuple(64508, 3535), tuple(91964, 33435), tuple(96686, 88673), tuple(66648, 64594), tuple(17927, 30539), tuple(73615, 22800), tuple(18580, 48077), tuple(59803, 48202), + tuple(76805, 89886), tuple(2744, 52965), tuple(55596, 22519), tuple(35358, 11629), tuple(83029, 80047), tuple(36120, 91930), tuple(26066, 23035), tuple(48857, 14268), tuple(63020, 26197), tuple(60623, 23252), tuple(34911, 72754), tuple(34808, 21593), tuple(64067, 58963), tuple(34509, 8739), tuple(52686, 96405), tuple(98282, 10463), tuple(6495, 64680), tuple(59016, 86968), tuple(33928, 51222), tuple(39609, 84992), tuple(67603, 89875), tuple(14723, 16144), tuple(30751, 46856), tuple(76874, 75024), tuple(89584, 58806), tuple(51278, 4113), tuple(27187, 93483), tuple(80039, 52159), tuple(6132, 25127), tuple(42358, 77498), tuple(33838, 79064), tuple(74147, 76851), tuple(39752, 27366), tuple(44888, 9809), tuple(10887, 4135), tuple(22303, 36417), tuple(58690, 34613), tuple(53998, 74014), tuple(71567, 32438), tuple(65110, 93406), tuple(77365, 41299), tuple(18044, 70636), tuple(77346, 21236), tuple(78408, 245), tuple(57704, 34662), tuple(75258, 64730), tuple(96992, 15533), tuple(56010, 60769), tuple(69163, 4826), tuple(88709, 20725), tuple(33197, 69743), tuple(97169, 83194), tuple(75277, 53343), tuple(14531, 64740), tuple(19997, 4752), tuple(74016, 55946), tuple(55290, 63626), tuple(32533, 32920), tuple(32946, 74610), tuple(12386, 33853), tuple(34825, 35374), tuple(28772, 32716), tuple(17280, 42683), tuple(54184, 34332), tuple(29964, 16203), tuple(65767, 61448), tuple(29133, 35728), tuple(6861, 14160), tuple(65483, 40224), tuple(78335, 76002), tuple(3061, 40615), tuple(11780, 87517), tuple(46135, 73448), tuple(10920, 72592), tuple(15696, 28810), tuple(44154, 64134), tuple(59365, 27248), tuple(76601, 39862), tuple(68264, 30019), tuple(48572, 54575), tuple(59499, 85796), tuple(35064, 23789), tuple(57028, 83545), tuple(33911, 8463), tuple(21827, 67966), tuple(15983, 69649), tuple(13919, 20584), tuple(82742, 67956), tuple(75457, 45767), tuple(55394, 62309), tuple(6099, 67510), tuple(58078, 9594), tuple(24511, 83149), tuple(24781, 79624), tuple(39745, 777), tuple(92023, 40085), tuple(22889, 37179), tuple(17919, 28607), tuple(79865, 72682), tuple(99829, 38190), tuple(21273, 21278), tuple(88299, 23433), tuple(88887, 48163), tuple(62993, 61567), tuple(82107, 84224), tuple(65049, 61245), tuple(75113, 93564), tuple(81562, 7874), tuple(32314, 32313), tuple(3979, 46996), tuple(40558, 93278), tuple(58758, 68163), tuple(40502, 58941), tuple(76961, 65762), tuple(48032, 36117), tuple(64712, 9137), tuple(12092, 56665), tuple(12315, 66581), tuple(20954, 29083), tuple(57317, 48290), tuple(23534, 86828), tuple(4869, 35950), tuple(26993, 24840), tuple(93007, 45049), tuple(18009, 20350), tuple(43053, 71248), tuple(47320, 66119), tuple(50898, 96627), tuple(669, 40018), tuple(89236, 44039), tuple(47375, 63306), tuple(61906, 6658), tuple(2672, 84546), tuple(59778, 72319), tuple(14497, 71952), tuple(42420, 87023), tuple(96465, 46140), tuple(32857, 22772), tuple(4985, 35125), tuple(61918, 28016), tuple(90275, 24406), tuple(49799, 10811), tuple(74137, 63345), tuple(26135, 86306), tuple(92971, 65541), tuple(40134, 95892), tuple(38554, 46307), tuple(48113, 16343), tuple(63990, 66283), tuple(17793, 49570), tuple(21736, 79819), tuple(13831, 27523), tuple(8939, 93929), tuple(96577, 4909), tuple(38583, 32781), tuple(13701, 24436), tuple(43444, 56054), tuple(17166, 32346), tuple(57202, 26264), tuple(82858, 75049), tuple(46317, 95666), tuple(54911, 68161), tuple(3894, 38521), tuple(26456, 30270), tuple(65214, 35331), tuple(41143, 13109), tuple(85441, 48899), tuple(93226, 25027), tuple(77045, 81171), tuple(30345, 79232), tuple(71167, 40854), tuple(58761, 56824), tuple(89047, 85314), tuple(31686, 81947), tuple(74946, 60661), tuple(49903, 13625), tuple(76341, 69067), tuple(46963, 88891), tuple(97223, 5921), tuple(52143, 9828), tuple(17413, 42731), tuple(30236, 93426), tuple(14540, 17652), tuple(52251, 97233), tuple(41581, 30097), tuple(28771, 46426), tuple(36260, 45179), tuple(4068, 16410), tuple(3146, 95055), tuple(5993, 88855), tuple(46103, 30022), tuple(26667, 18756), tuple(54576, 13438), tuple(12800, 11258), tuple(80761, 44979), tuple(59811, 76627), tuple(77917, 87270), tuple(46286, 28657), tuple(30609, 86852), tuple(15200, 28936), tuple(86331, 34195), tuple(98461, 55054), tuple(91760, 62792), tuple(91551, 70192), tuple(96030, 78205), tuple(8254, 27057), tuple(600, 37830), tuple(58635, 65506), tuple(81661, 73708), tuple(11225, 24255), tuple(15830, 9029), tuple(84384, 46190), tuple(31344, 25765), tuple(25670, 30716), tuple(88507, 19484), tuple(28207, 45941), tuple(91874, 15786), tuple(10094, 10934), tuple(38013, 2179), tuple(14558, 36415), tuple(65079, 48850), tuple(65486, 85046), tuple(54958, 60275), tuple(99800, 96623), tuple(68895, 99829), tuple(3708, 75830), tuple(96368, 22631), tuple(99411, 50094), tuple(56888, 3883), tuple(87288, 45604), tuple(64512, 84543), tuple(45565, 14170), tuple(77114, 15132), tuple(31800, 70333), tuple(57775, 40548), tuple(31788, 67511), tuple(51929, 13684), tuple(53736, 81543), tuple(84251, 86303), tuple(63823, 83258), tuple(77539, 61381), tuple(43570, 39418), tuple(79859, 34773), tuple(8595, 64524), tuple(97242, 9283), tuple(15530, 84591), tuple(75535, 65546), tuple(16516, 50162), tuple(58815, 1815), tuple(34897, 82920), tuple(66215, 81262), tuple(81487, 4902), tuple(64039, 25703), tuple(78006, 90468), tuple(3081, 26910), tuple(58159, 4777), tuple(73715, 36375), tuple(69189, 60971), tuple(18169, 39587), tuple(57960, 57668), tuple(6582, 63707), tuple(11155, 47930), tuple(70829, 92266), tuple(6294, 92305), tuple(2188, 6419), tuple(17141, 54972), tuple(60240, 35276), tuple(10788, 29414), tuple(17464, 76377), tuple(3994, 17227), tuple(12039, 24992), tuple(1340, 77467), tuple(1212, 41758), tuple(52186, 80763), tuple(970, 78819), tuple(92897, 68714), tuple(6349, 77016), tuple(22069, 77732), tuple(78209, 72708), tuple(71986, 56770), tuple(8580, 87225), tuple(97505, 63546), tuple(67459, 39771), tuple(50707, 57066), tuple(68226, 54176), tuple(65425, 27407), tuple(57723, 19288), tuple(56974, 90449), tuple(55878, 1264), tuple(46939, 79863), tuple(34868, 4652), tuple(39872, 78482), tuple(92657, 20961), tuple(99690, 28825), tuple(33761, 52922), tuple(73738, 64995), tuple(92092, 3237), tuple(2463, 45045), tuple(43984, 69864), tuple(60146, 5333), tuple(58127, 79082), tuple(84395, 73949), tuple(50818, 68457), tuple(48585, 47420), tuple(60878, 67337), tuple(16573, 30621), tuple(46524, 14168), tuple(87995, 44854), tuple(73143, 77177), tuple(33967, 37276), tuple(95038, 17670), tuple(69022, 16038), tuple(58485, 90526), tuple(1705, 1443), tuple(97969, 40011), tuple(14719, 42770), tuple(8695, 27192), tuple(47546, 51349), tuple(75263, 24419), tuple(25420, 66286), tuple(39198, 41401), tuple(77896, 85583), tuple(28265, 76766), tuple(88836, 48759), tuple(47768, 39582), tuple(65103, 3167), tuple(92171, 85360), tuple(1549, 79296), tuple(71725, 16645), tuple(87349, 29290), tuple(66201, 61712), tuple(43525, 70338), tuple(99025, 63090), tuple(3687, 79963), tuple(63600, 92088), tuple(2480, 1359), tuple(31384, 63603), tuple(29650, 24391), tuple(8552, 82260), tuple(16729, 29139), tuple(26503, 4767), tuple(88945, 19824), tuple(66695, 95696), tuple(84016, 35417), tuple(71521, 22206), tuple(88433, 55606), tuple(66380, 81316), tuple(30573, 36000), tuple(85223, 20494), tuple(99672, 82813), tuple(65500, 78258), tuple(55817, 98414), tuple(43248, 53800), tuple(62787, 21018), tuple(48981, 36258), tuple(41216, 98585), tuple(18576, 18004), tuple(27272, 72860), tuple(76774, 87664), tuple(26737, 11514), tuple(24472, 42538), tuple(5860, 81355), tuple(29066, 10012), tuple(75308, 28561), tuple(23609, 10007), tuple(10007, 19146), tuple(15568, 1487), tuple(80743, 85294), tuple(11207, 90623), tuple(61258, 63879), tuple(34363, 59005), tuple(74884, 2528), tuple(26604, 52738), tuple(33304, 1202), tuple(20381, 18984), tuple(81968, 92425), tuple(4407, 84677), tuple(2112, 79756), tuple(46970, 4367), tuple(36854, 23482), tuple(88346, 75107), tuple(10643, 31806), tuple(21351, 5590), tuple(69317, 53292), tuple(76711, 10085), tuple(70333, 90592), tuple(88818, 822), tuple(23927, 48141), tuple(84710, 33870), tuple(96932, 22686), tuple(5783, 87468), tuple(7785, 11585), tuple(49497, 33764), tuple(13506, 55969), tuple(37840, 78455), tuple(21532, 22292), tuple(97306, 42065), tuple(6579, 40749), tuple(2593, 4995), tuple(81985, 23611), tuple(63888, 98317), tuple(44975, 83777), tuple(57688, 42688), tuple(641, 45787), tuple(7316, 1967), tuple(43837, 18274), tuple(89994, 32770), tuple(4285, 50388), tuple(84699, 41841), tuple(19564, 20683), tuple(76027, 62278), tuple(26140, 11288), tuple(39656, 79954), tuple(16718, 17335), tuple(11583, 21283), tuple(55441, 32178), tuple(6810, 87225), tuple(27191, 54323), tuple(53406, 31512), tuple(48003, 80077), tuple(78497, 29570), tuple(39140, 66619), tuple(12651, 44576), tuple(1761, 88410), tuple(47139, 20766), tuple(39183, 69367), tuple(80479, 23285), tuple(1568, 78535), tuple(18476, 35058), tuple(93551, 81063), tuple(12059, 60021), tuple(23356, 26572), tuple(79975, 35434), tuple(82230, 67436), tuple(20243, 92343), tuple(47809, 10634), tuple(69537, 60167), tuple(3873, 77404), tuple(1136, 27956), tuple(17470, 24156), tuple(35849, 19150), tuple(74760, 37961), tuple(36660, 44448), tuple(36009, 96619), tuple(87110, 84921), tuple(16080, 60637), tuple(36046, 17351), tuple(96403, 99978), tuple(11060, 68629), tuple(36081, 23464), tuple(4684, 11817), tuple(50126, 82936), tuple(55262, 54135), tuple(53717, 66293), tuple(58028, 28065), tuple(92791, 99766), tuple(46266, 77711), tuple(61912, 65782), tuple(38677, 41158), tuple(4001, 46340), tuple(70987, 12784), tuple(14819, 42857), tuple(78985, 99956), tuple(79737, 42497), tuple(55305, 7329), tuple(64103, 24170), tuple(49093, 22115), tuple(2465, 97282), tuple(29009, 15663), tuple(80976, 86477), tuple(16439, 56685), tuple(53482, 15293), tuple(5038, 5991), tuple(67060, 84201), tuple(54350, 38095), tuple(67539, 68292), tuple(26464, 64908), tuple(92909, 12867), tuple(83517, 26474), tuple(76081, 85247), tuple(23250, 66616), + tuple(20783, 34330), tuple(43074, 10165), tuple(93968, 70375), tuple(83802, 70820), tuple(19871, 63094), tuple(35699, 36506), tuple(23905, 2401), tuple(27847, 31968), tuple(76714, 44112), tuple(62599, 32720), tuple(10362, 81985), tuple(35708, 2090), tuple(13071, 39035), tuple(71851, 59493), tuple(62833, 48082), tuple(77164, 22804), tuple(6469, 43229), tuple(92051, 3719), tuple(51910, 77689), tuple(91470, 63253), tuple(57914, 57836), tuple(98819, 97813), tuple(35975, 488), tuple(51431, 34061), tuple(45414, 85971), tuple(56563, 93517), tuple(40789, 53103), tuple(9242, 20814), tuple(784, 22584), tuple(8740, 56894), tuple(28504, 378), tuple(8287, 96930), tuple(74232, 97496), tuple(61565, 7904), tuple(9779, 45122), tuple(33767, 48471), tuple(16766, 10722), tuple(47764, 478), tuple(14374, 30099), tuple(89134, 19977), tuple(60860, 93201), tuple(71123, 29840), tuple(57159, 34410), tuple(82411, 99537), tuple(11307, 3733), tuple(70264, 43028), tuple(30418, 19372), tuple(46543, 31506), tuple(33043, 98980), tuple(21137, 63374), tuple(85640, 36957), tuple(6790, 60751), tuple(78771, 43700), tuple(33808, 38263), tuple(27232, 35152), tuple(39925, 5062), tuple(3120, 65621), tuple(39319, 6795), tuple(77468, 94964), tuple(10481, 43009), tuple(24237, 2103), tuple(16837, 55667), tuple(43846, 2874), tuple(78786, 66811), tuple(92185, 62395), tuple(26318, 87942), tuple(6208, 80815), tuple(66952, 71885), tuple(51435, 25450), tuple(21443, 69801), tuple(92554, 81977), tuple(58912, 82288), tuple(59681, 46177), tuple(60397, 65866), tuple(72065, 13318), tuple(2848, 73852), tuple(7577, 83238), tuple(209, 40659), tuple(72103, 15266), tuple(23365, 67286), tuple(14600, 29269), tuple(85541, 63289), tuple(25427, 54812), tuple(22967, 54965), tuple(81525, 27126), tuple(20473, 55455), tuple(84067, 25794), tuple(46798, 79332), tuple(93825, 74677), tuple(447, 5904), tuple(65661, 92916), tuple(54428, 76482), tuple(1025, 34415), tuple(63761, 30038), tuple(93025, 15090), tuple(98807, 93426), tuple(57562, 59615), tuple(84884, 30620), tuple(75066, 71824), tuple(51199, 37934), tuple(95530, 15260), tuple(513, 98278), tuple(62995, 28267), tuple(47535, 69776), tuple(39266, 4696), tuple(14742, 13225), tuple(44268, 16548), tuple(45976, 41680), tuple(99638, 30285), tuple(85609, 5578), tuple(28156, 12884), tuple(76188, 86573), tuple(44639, 15480), tuple(86789, 72636), tuple(18702, 13337), tuple(96638, 59398), tuple(90988, 26909), tuple(85069, 95193), tuple(67262, 38337), tuple(51694, 19659), tuple(93341, 80988), tuple(48733, 88460), tuple(55630, 22866), tuple(96203, 10316), tuple(30644, 68318), tuple(79292, 63136), tuple(60185, 73681), tuple(60474, 19078), tuple(48721, 82811), tuple(19713, 99527), tuple(17537, 55235), tuple(296, 8353), tuple(58691, 72158), tuple(66734, 92490), tuple(87642, 7174), tuple(78285, 35337), tuple(19503, 14273), tuple(10713, 64116), tuple(85966, 98738), tuple(56561, 99347), tuple(14869, 89963), tuple(95126, 30748), tuple(89272, 79060), tuple(69888, 7193), tuple(32583, 74564), tuple(95542, 52128), tuple(78360, 42675), tuple(86062, 68404), tuple(38732, 21411), tuple(92935, 45415), tuple(99027, 83925), tuple(73232, 37405), + tuple(97079, 87722), tuple(49453, 61633), tuple(53860, 29672), tuple(29513, 42837), tuple(47802, 37592), tuple(12469, 34249), tuple(42792, 53643), tuple(62613, 70068), tuple(82526, 73215), tuple(72285, 11113), tuple(42500, 55478), tuple(43717, 95240), tuple(43797, 75361), tuple(24335, 33138), tuple(38245, 66964), tuple(20717, 95342), tuple(64691, 18064), tuple(48154, 59381), tuple(25699, 77506), tuple(67122, 65358), tuple(4706, 47639), tuple(39616, 49499), tuple(81811, 43780), tuple(835, 85236), tuple(55259, 36091), tuple(66392, 64552), tuple(18111, 14142), tuple(3313, 24306), tuple(16039, 50370), tuple(13767, 95591), tuple(3619, 17285), tuple(91602, 86378), tuple(65370, 31997), tuple(73103, 79544), tuple(56207, 1833), tuple(83803, 12639), tuple(99772, 62410), tuple(48525, 27025), tuple(4843, 17363), tuple(90649, 69831), tuple(38294, 83908), tuple(62986, 50254), tuple(80915, 86505), tuple(77831, 38427), tuple(65269, 10998), tuple(18364, 35533), tuple(90495, 89902), tuple(18124, 73639), tuple(37972, 64523), tuple(59756, 55630), tuple(96021, 46676), tuple(62423, 13536), tuple(57039, 79285), tuple(22584, 69218), tuple(82257, 47164), tuple(85219, 84268), tuple(99430, 87817), tuple(54061, 57126), tuple(95756, 20489), tuple(27341, 67329), tuple(26826, 81082), tuple(86892, 10021), tuple(76753, 35118), tuple(45122, 27808), tuple(16706, 37697), tuple(54734, 85826), tuple(61753, 99199), tuple(54920, 42265), tuple(79397, 32234), tuple(95638, 71031), tuple(66412, 11193), tuple(1874, 46395), tuple(43748, 82517), tuple(99596, 63908), tuple(83987, 8436), tuple(52027, 64590), tuple(2821, 71063), tuple(38625, 47246), tuple(64890, 18073), tuple(78221, 45134), tuple(51729, 8336), tuple(7235, 32732), tuple(69849, 4355), tuple(66632, 29817), tuple(87115, 20363), tuple(95882, 30431), tuple(56386, 94579), tuple(90145, 75474), tuple(41608, 31413), tuple(9284, 22127), tuple(60184, 97820), tuple(70813, 48129), tuple(84426, 2932), tuple(74599, 76277), tuple(19551, 2074), tuple(83741, 31228), tuple(24540, 69367), tuple(66373, 48734), tuple(1043, 52758), tuple(55207, 67301), tuple(68930, 95643), tuple(60576, 84717), tuple(87418, 61921), tuple(40078, 11839), tuple(26131, 84239), tuple(57553, 30194), tuple(85992, 83655), tuple(9469, 26355), tuple(7871, 58669), tuple(66599, 94551), tuple(73474, 91775), tuple(49288, 37125), tuple(64459, 41703), tuple(20761, 11140), tuple(18453, 75828), tuple(7666, 3242), tuple(3851, 64702), tuple(99727, 5458), tuple(66247, 1430), tuple(53801, 94055), tuple(18633, 22045), tuple(5594, 41215), tuple(23845, 66849), tuple(51801, 46932), tuple(63960, 28483), tuple(41699, 56219), tuple(40125, 68122), tuple(1809, 49948), tuple(39206, 71380), tuple(29721, 38251), tuple(10858, 91494), tuple(33459, 29030), tuple(230, 28395), tuple(45666, 41675), tuple(31763, 68954), tuple(28498, 58275), tuple(27329, 14755), tuple(98543, 32649), tuple(26836, 19108), tuple(31349, 45705), tuple(89891, 19691), tuple(42716, 14912), tuple(34712, 4213), tuple(72574, 37957), tuple(29648, 54691), tuple(77851, 61441), tuple(62360, 25693), tuple(78942, 30840), tuple(58808, 36761), tuple(39400, 96765), tuple(77844, 33261), tuple(98738, 80688), tuple(99234, 82018), tuple(49364, 46291), tuple(12030, 32499), tuple(42946, 19435), tuple(34021, 40823), tuple(54070, 84294), tuple(76238, 50858), tuple(94576, 62781), tuple(4823, 17885), tuple(55861, 33029), tuple(43468, 78885), tuple(15775, 25990), tuple(2481, 64154), tuple(65398, 30074), tuple(85540, 50290), tuple(28926, 8236), tuple(75476, 56523), tuple(51363, 82037), tuple(97952, 75624), tuple(71526, 55313), tuple(55143, 49146), tuple(11616, 79576), tuple(83981, 24799), tuple(30197, 96196), tuple(46658, 64430), tuple(34062, 422), tuple(91483, 37099), tuple(88286, 27917), tuple(92932, 21740), tuple(66567, 3590), tuple(35787, 37973), tuple(22601, 93171), tuple(91215, 51041), tuple(41702, 3198), tuple(78731, 89390), tuple(46850, 34544), tuple(49404, 10082), tuple(6393, 62145), tuple(39241, 12836), tuple(10383, 56740), tuple(50850, 84828), tuple(39908, 95738), tuple(78309, 9041), tuple(7898, 34833), tuple(80987, 44693), tuple(66170, 90006), tuple(57599, 82993), tuple(33458, 68423), tuple(67786, 72838), tuple(20364, 89240), tuple(66760, 10965), tuple(77090, 39427), tuple(8706, 77011), tuple(76225, 66045), tuple(24829, 16580), tuple(29040, 10745), tuple(25973, 68024), tuple(42886, 90000), tuple(5125, 90725), tuple(71675, 42961), tuple(88074, 15503), tuple(7096, 77238), tuple(12467, 7224), tuple(94344, 88876), tuple(91643, 6834), tuple(99776, 88805), tuple(88992, 21613), tuple(27629, 72345), tuple(99262, 53013), tuple(84894, 7422), tuple(86469, 44852), tuple(44709, 82358), tuple(90338, 63426), tuple(70093, 65813), tuple(18014, 91297), tuple(38135, 18842), tuple(83643, 25418), tuple(61985, 23996), tuple(63495, 91872), tuple(65518, 85038), tuple(19747, 18165), tuple(60916, 55986), tuple(73826, 68279), tuple(26147, 73224), tuple(79606, 35342), tuple(84063, 47648), tuple(41115, 19541), tuple(3710, 46873), tuple(79926, 96227), tuple(77885, 38548), tuple(31121, 40100), tuple(17197, 42700), tuple(89898, 65060), tuple(70854, 69897), tuple(47212, 78340), tuple(8871, 20368), tuple(81502, 76700), tuple(6251, 92364), tuple(20652, 81152), tuple(60197, 15839), tuple(57972, 74525), tuple(51527, 19454), tuple(43081, 37404), tuple(11551, 38858), tuple(73710, 36789), tuple(99064, 62900), tuple(16292, 61362), tuple(5438, 13708), tuple(65610, 23813), tuple(14701, 66586), tuple(96560, 25606), tuple(6101, 50386), tuple(76171, 13159), tuple(453, 51097), tuple(80871, 29995), tuple(65414, 10781), tuple(56201, 59852), tuple(57872, 29305), tuple(85387, 49642), tuple(98332, 45308), tuple(78934, 88320), tuple(27288, 84343), tuple(71539, 48945), tuple(17348, 35121), tuple(51107, 73807), tuple(60739, 89966), tuple(49803, 53931), tuple(91339, 18943), tuple(66923, 8421), tuple(1314, 61554), tuple(56175, 73062), tuple(1215, 51606), tuple(16335, 1289), tuple(62888, 62858), tuple(26620, 51572), tuple(19757, 93782), tuple(95016, 49464), tuple(77323, 61370), tuple(14358, 40637), tuple(75344, 25972), tuple(12606, 53465), tuple(22258, 96976), tuple(36276, 85574), tuple(93544, 82426), tuple(50554, 1078), tuple(54132, 59093), tuple(83143, 37847), tuple(36778, 7827), tuple(42525, 47562), tuple(48399, 16894), tuple(48812, 94330), tuple(2197, 63615), tuple(16681, 83461), tuple(61452, 74775), tuple(33179, 39047), tuple(11357, 45663), tuple(34429, 3118), tuple(97453, 71262), tuple(76788, 9452), tuple(42050, 94414), tuple(62412, 57976), tuple(10366, 59637), tuple(91804, 41509), tuple(66410, 60144), tuple(20517, 85756), tuple(16402, 50019), tuple(33062, 94128), tuple(66717, 95079), tuple(80801, 53200), tuple(43638, 16443), tuple(68690, 30310), tuple(78330, 31709), tuple(53288, 51831), tuple(59612, 15340), tuple(69197, 67661), tuple(25729, 54544), tuple(61292, 3077), tuple(91198, 68925), tuple(94243, 84911), tuple(81175, 41496), tuple(56087, 30799), tuple(19192, 5965), tuple(6401, 98593), tuple(90599, 40564), tuple(99636, 3224), tuple(13595, 15079), tuple(81758, 98510), tuple(31894, 87256), tuple(32717, 15856), tuple(58045, 25722), tuple(80820, 39359), tuple(89127, 50007), tuple(57129, 30173), tuple(143, 82490), tuple(67320, 89298), tuple(78031, 70771), tuple(56372, 13856), tuple(53792, 93923), tuple(77536, 97686), tuple(34281, 88893), tuple(7720, 38598), tuple(42577, 15445), tuple(97049, 25292), tuple(5755, 75274), tuple(68500, 88440), tuple(65460, 91968), tuple(82251, 62700), tuple(58737, 28221), tuple(33966, 31858), tuple(89283, 6137), tuple(95713, 57892), tuple(64716, 41893), tuple(23226, 72596), tuple(77494, 1226), tuple(57456, 97085), tuple(56638, 73195), tuple(86791, 95487), tuple(38616, 3710), tuple(27612, 88402), tuple(86211, 61383), tuple(74751, 67963), tuple(35294, 45969), tuple(20040, 65633), tuple(46379, 55793), tuple(5254, 33070), tuple(96039, 46828), tuple(53169, 86515), tuple(61456, 32728), tuple(19306, 28894), tuple(266, 73943), tuple(6298, 78481), tuple(55429, 72954), tuple(4013, 62916), tuple(19413, 82227), tuple(97767, 41262), tuple(1754, 66034), tuple(62168, 95138), tuple(8502, 1232), tuple(87736, 22730), tuple(94519, 57526), tuple(47840, 52733), tuple(57430, 11063), tuple(48203, 88666), tuple(94187, 17306), tuple(51254, 3414), tuple(42847, 70850), tuple(30517, 37298), tuple(51002, 3187), tuple(69065, 57819), tuple(28158, 31948), tuple(28641, 57066), tuple(64401, 41541), tuple(16769, 93104), tuple(36026, 40379), tuple(89972, 21007), tuple(23129, 3532), tuple(25076, 78327), tuple(91716, 52771), tuple(85414, 74704), tuple(25078, 29180), tuple(82397, 27229), tuple(71809, 86957), tuple(84698, 34879), tuple(28573, 40238), tuple(79803, 740), tuple(9445, 37484), tuple(30310, 44337), tuple(48396, 61468), tuple(55206, 32145), tuple(85429, 8394), tuple(57022, 16754), tuple(20686, 31181), tuple(49381, 90708), tuple(86368, 80026), tuple(12503, 98384), tuple(17987, 17590), tuple(87975, 47488), tuple(1917, 40089), tuple(28921, 51966), tuple(75061, 47560), tuple(47682, 85166), tuple(44983, 43829), tuple(65132, 39721), tuple(63156, 48271), tuple(43469, 44812), tuple(92402, 52827), tuple(93574, 93874), tuple(49160, 14154), tuple(17068, 32747), tuple(24013, 48763), tuple(44388, 91612), tuple(50092, 46361), tuple(12638, 67958), tuple(22733, 48580), tuple(89692, 17614), tuple(76259, 80333), tuple(60667, 81071), tuple(11866, 60670), tuple(44127, 52256), tuple(91538, 16284), tuple(3947, 5775), tuple(24013, 87274), tuple(61890, 35907), tuple(40033, 65872), tuple(82217, 28133), tuple(92448, 66250), tuple(69722, 79165), tuple(45642, 94585), tuple(19332, 52617), tuple(68376, 74661), tuple(67538, 36822), tuple(44251, 51303), tuple(21737, 91360), tuple(89816, 80022), tuple(62003, 95863), tuple(91553, 89883), tuple(81327, 60251), tuple(79081, 77218), tuple(83875, 50172), tuple(64753, 45810), tuple(31661, 24768), tuple(37225, 43323), tuple(7290, 90747), tuple(83726, 40577), tuple(67955, 25873), tuple(64937, 91179), tuple(43298, 1399), tuple(63408, 89816), tuple(7356, 46305), tuple(45184, 57862), tuple(53297, 20667), tuple(31709, 43903), tuple(62673, 94822), tuple(27913, 75493), tuple(24687, 80894), tuple(98262, 61113), tuple(53123, 55460), tuple(35147, 99271), tuple(27646, 34622), tuple(73077, 30910), tuple(20512, 11203), tuple(33770, 99560), tuple(34580, 35708), tuple(67059, 99164), tuple(72256, 23281), tuple(92534, 87165), tuple(52774, 85396), tuple(56154, 92895), tuple(24460, 62535), tuple(56634, 4948), tuple(26182, 65572), tuple(99426, 1748), tuple(31410, 43026), tuple(24172, 44480), tuple(9426, 61375), tuple(21718, 32700), tuple(91428, 80453), tuple(27315, 90992), tuple(2743, 10613), tuple(31248, 75906), tuple(99086, 51477), tuple(44829, 14817), tuple(89794, 9674), tuple(88775, 1393), tuple(94268, 66168), tuple(76314, 51601), tuple(30142, 76441), tuple(39895, 74493), tuple(67323, 13617), tuple(54056, 77441), tuple(64209, 30237), tuple(81819, 2685), tuple(74961, 36558), tuple(54405, 11789), tuple(47419, 18927), tuple(95646, 97923), tuple(6793, 98367), tuple(84729, 55346), tuple(26209, 51661), tuple(88902, 47479), tuple(29248, 6257), tuple(90293, 56023), tuple(13659, 85240), tuple(33402, 22946), tuple(98715, 46806), tuple(59061, 14084), tuple(63647, 85523), tuple(16920, 66956), tuple(33806, 17029), tuple(5921, 55022), tuple(56918, 8478), tuple(26353, 8772), tuple(73846, 62583), tuple(66724, 13905), tuple(81927, 13344), tuple(8535, 73788), tuple(42475, 864), tuple(43233, 31055), tuple(25826, 92107), tuple(58400, 93558), tuple(76480, 27917), tuple(11783, 45463), tuple(1994, 30049), tuple(69277, 48157), tuple(64234, 49337), tuple(71741, 56314), tuple(2005, 69772), tuple(49003, 37695), tuple(39968, 77681), tuple(832, 10155), tuple(57104, 19308), tuple(96734, 11547), tuple(30184, 42421), tuple(48375, 44830), tuple(93937, 72937), tuple(90182, 73901), tuple(15777, 13356), tuple(23590, 41957), tuple(28339, 72344), tuple(57738, 11792), tuple(46981, 22885), tuple(89701, 63079), tuple(18853, 8142), tuple(71023, 86607), tuple(43044, 84076), tuple(15504, 63914), tuple(10852, 24752), tuple(84420, 8955), tuple(52478, 86472), tuple(31493, 34784), tuple(63120, 80839), tuple(99483, 7075), tuple(63463, 9701), tuple(72217, 81768), tuple(92665, 41759), tuple(61299, 30348), tuple(75839, 10811), tuple(40924, 73497), tuple(16847, 11969), tuple(62221, 40296), tuple(86514, 6737), tuple(71717, 21760), tuple(72280, 22605), tuple(84073, 26361), tuple(35313, 38026), tuple(88244, 41921), tuple(2395, 44993), tuple(43095, 4491), tuple(65029, 92486), tuple(77825, 37626), tuple(86268, 93758), tuple(12282, 96669), tuple(70109, 3854), tuple(88201, 48985), tuple(67432, 22291), tuple(71226, 78916), tuple(93242, 69896), tuple(45961, 28858), tuple(37543, 83277), tuple(33989, 19303), tuple(75997, 92827), tuple(81996, 50401), tuple(47766, 89974), tuple(6969, 58504), tuple(57495, 67704), tuple(42186, 15837), tuple(16266, 31543), tuple(53482, 57047), tuple(6741, 53863), tuple(69708, 62402), tuple(47622, 71680), tuple(56407, 59557), tuple(35497, 43626), tuple(94382, 72849), tuple(85322, 82494), tuple(48283, 84203), tuple(60187, 43506), tuple(30227, 72397), tuple(8179, 46362), tuple(91848, 6724), + tuple(44252, 49652), tuple(62329, 71957), tuple(48136, 53803), tuple(29408, 16811), tuple(2807, 35831), tuple(3982, 42400), tuple(31819, 922), tuple(60411, 29397), tuple(63298, 32886), tuple(56696, 94800), tuple(40452, 78058), tuple(72632, 46188), tuple(6187, 49011), tuple(41030, 50745), tuple(37287, 2821), tuple(85833, 58997), tuple(69513, 2449), tuple(67890, 79660), tuple(10510, 65067), tuple(81559, 31412), tuple(55173, 70275), tuple(30720, 65244), tuple(39362, 55066), tuple(82509, 54146), tuple(37012, 50941), tuple(7777, 73746), tuple(55324, 68529), tuple(64001, 14553), tuple(75092, 7732), tuple(30396, 68267), tuple(17785, 63304), tuple(60691, 75626), tuple(73360, 24028), tuple(49094, 44015), tuple(38186, 58436), tuple(85214, 87107), tuple(28851, 30981), tuple(97558, 16884), tuple(50485, 61227), tuple(66390, 14523), tuple(91346, 12746), tuple(27417, 80041), tuple(70675, 62543), tuple(30493, 34005), tuple(93733, 65419), tuple(84518, 73912), tuple(95889, 56587), tuple(25811, 87640), tuple(67088, 17670), tuple(61030, 10236), tuple(63615, 23071), tuple(95064, 2080), tuple(67171, 84194), tuple(29917, 74112), tuple(69466, 26813), tuple(65199, 34701), tuple(73665, 70408), tuple(79992, 52475), tuple(85736, 3601), tuple(37979, 55469), tuple(19825, 77218), tuple(31666, 7906), tuple(74130, 1569), tuple(51690, 48772), tuple(17872, 80141), tuple(26340, 29232), tuple(5680, 4004), tuple(72841, 60873), tuple(65725, 86711), tuple(39659, 76703), tuple(72206, 4834), tuple(25126, 62083), tuple(85881, 81324), tuple(36485, 89451), tuple(66626, 2033), tuple(23961, 13900), tuple(68404, 32573), tuple(6568, 75904), tuple(5463, 40836), tuple(82243, 72476), tuple(41469, 85222), tuple(53063, 80905), tuple(89420, 89405), tuple(64438, 54748), tuple(84609, 19925), tuple(58071, 76697), tuple(92927, 37184), tuple(86525, 43159), tuple(90683, 47762), tuple(4221, 94429), tuple(68456, 34730), tuple(5303, 27512), tuple(3857, 87130), tuple(25963, 49542), tuple(68981, 6398), tuple(16900, 38579), tuple(44288, 3921), tuple(41848, 6266), tuple(14235, 18205), tuple(93114, 74697), tuple(31693, 12438), tuple(93873, 3135), tuple(39867, 42033), tuple(39257, 83168), tuple(91557, 2168), tuple(25761, 99686), tuple(33891, 81917), tuple(69185, 25496), tuple(32937, 32667), tuple(53201, 77822), tuple(41625, 73595), tuple(75159, 2574), tuple(41500, 24049), tuple(18998, 17778), tuple(55319, 14793), tuple(98343, 55538), tuple(50306, 92789), tuple(8111, 36989), tuple(12332, 90370), tuple(50098, 64743), tuple(518, 42569), tuple(53218, 75332), tuple(37930, 85988), tuple(26622, 30733), tuple(72656, 87213), tuple(62011, 83799), tuple(74325, 39325), tuple(61424, 29292), tuple(38885, 35172), tuple(48893, 53493), tuple(5365, 46863), tuple(35192, 50130), tuple(67377, 31556), tuple(89291, 38089), tuple(7639, 18196), tuple(66102, 23782), tuple(94128, 13012), tuple(14739, 40637), tuple(38124, 70538), tuple(21143, 9114), tuple(81628, 1281), tuple(2385, 12814), tuple(97713, 12931), tuple(15392, 71469), tuple(285, 2139), tuple(75082, 86935), tuple(53815, 6664), tuple(21102, 26350), tuple(7191, 63079), tuple(77811, 54178), tuple(94993, 43113), tuple(23712, 9041), tuple(5151, 47040), tuple(48565, 21701), tuple(68877, 29339), tuple(41207, 91567), tuple(52928, 39020), tuple(90950, 13773), tuple(9269, 45202), tuple(76822, 23962), tuple(66347, 97641), tuple(39410, 6179), tuple(544, 78664), tuple(6168, 22720), tuple(41653, 97913), tuple(17421, 50726), tuple(7841, 71433), tuple(54395, 26607), tuple(4269, 30336), tuple(34319, 79247), tuple(95612, 91933), tuple(25657, 23904), tuple(19990, 4678), tuple(87858, 51586), tuple(5060, 74367), tuple(56282, 50346), tuple(24967, 12978), tuple(5413, 84898), tuple(83630, 81450), tuple(4445, 3246), tuple(8686, 37833), tuple(25753, 491), tuple(64949, 79083), tuple(91227, 99361), tuple(15478, 9776), tuple(19138, 1197), tuple(90231, 21775), tuple(1603, 3420), tuple(80483, 91945), tuple(26254, 47364), tuple(39956, 39011), tuple(21944, 68718), tuple(17476, 26688), tuple(35124, 95520), tuple(80675, 86048), tuple(37802, 24654), tuple(35991, 30501), tuple(58201, 32076), tuple(73425, 48851), tuple(32081, 62678), tuple(43890, 72473), tuple(55420, 55864), tuple(92730, 83636), tuple(98991, 57739), tuple(16554, 8671), tuple(97393, 74717), tuple(52946, 40432), tuple(54038, 57550), tuple(28407, 59994), tuple(51960, 69485), tuple(54362, 59837), tuple(56608, 44803), tuple(87765, 65240), tuple(83537, 20410), tuple(12462, 63600), tuple(29652, 60603), tuple(33694, 86009), tuple(6328, 2247), tuple(1163, 66579), tuple(14339, 11994), tuple(84291, 50111), tuple(68889, 88342), tuple(10269, 72875), tuple(66319, 32677), tuple(13064, 29930), tuple(32190, 83783), tuple(45970, 36250), tuple(76934, 56387), tuple(86991, 52198), tuple(595, 49931), tuple(56487, 35023), tuple(64301, 3898), tuple(62751, 16083), tuple(76962, 42724), tuple(25144, 84082), tuple(42577, 55365), tuple(35491, 62043), tuple(98690, 95354), tuple(78142, 63556), tuple(43994, 19756), tuple(44371, 88026), tuple(79528, 38378), tuple(60538, 95096), tuple(94043, 64914), tuple(56328, 52212), tuple(23125, 3718), tuple(68265, 31800), tuple(50257, 30242), tuple(90023, 16264), tuple(26536, 54846), tuple(56408, 26069), tuple(48835, 90685), tuple(41440, 85486), tuple(50439, 28977), tuple(57270, 58062), tuple(93385, 81991), tuple(41747, 90412), tuple(4397, 54135), tuple(27833, 63238), tuple(30047, 54689), tuple(97424, 22639), tuple(38666, 7212), tuple(11002, 23871), tuple(94214, 17282), tuple(38570, 36544), tuple(21281, 2550), tuple(18772, 9450), tuple(21573, 89501), tuple(72980, 3658), tuple(4270, 75217), tuple(84311, 52335), tuple(50238, 7027), tuple(79880, 13083), tuple(4453, 53612), tuple(42094, 83535), tuple(26820, 29389), tuple(68926, 37356), tuple(41068, 99341), tuple(17804, 36252), tuple(95293, 20765), tuple(16191, 10046), tuple(97430, 9242), tuple(8161, 65278), tuple(57448, 35098), tuple(94391, 77130), tuple(98916, 39103), tuple(20350, 32970), tuple(90646, 11890), tuple(75362, 5602), tuple(27639, 77663), tuple(43360, 46034), tuple(22402, 35513), tuple(8137, 28845), tuple(85004, 55522), tuple(41422, 53954), tuple(31450, 3352), tuple(43577, 62316), tuple(2055, 68345), tuple(81241, 88166), tuple(99688, 49801), tuple(34150, 62685), tuple(61452, 89940), tuple(17271, 17048), tuple(35360, 54074), tuple(24514, 86758), tuple(65291, 94634), tuple(56371, 29354), tuple(17017, 58323), tuple(97782, 38903), tuple(64924, 7863), tuple(26686, 44764), tuple(6946, 65671), tuple(19164, 55697), tuple(53736, 61363), tuple(16698, 88605), tuple(68917, 45223), tuple(61620, 71030), tuple(36833, 87), tuple(25499, 92341), tuple(64999, 60843), tuple(10332, 23741), tuple(44183, 74772), tuple(5876, 83182), tuple(2777, 13943), tuple(30518, 90419), tuple(95186, 2879), tuple(67770, 28915), tuple(63386, 30643), tuple(32598, 27470), tuple(22690, 14598), tuple(33055, 49882), tuple(66771, 87914), tuple(1528, 77971), tuple(35398, 19178), tuple(66537, 4756), tuple(45085, 80236), tuple(67054, 78236), tuple(98986, 54864), tuple(22249, 20937), tuple(63417, 4603), tuple(77613, 1198), tuple(6611, 68649), tuple(73627, 56112), tuple(73633, 97606), tuple(99775, 39893), tuple(56752, 97490), tuple(32399, 69269), tuple(62186, 76302), tuple(94184, 83140), tuple(75653, 83050), tuple(61775, 15249), tuple(47463, 90032), tuple(21937, 11962), tuple(62241, 55183), tuple(98504, 4933), tuple(66272, 28609), tuple(67746, 30488), tuple(54196, 35321), tuple(26259, 63765), tuple(11312, 41065), tuple(15815, 63183), tuple(18767, 28578), tuple(88996, 89259), tuple(5635, 82121), tuple(82835, 33221), tuple(23282, 57401), tuple(32823, 83397), tuple(9333, 22645), tuple(93949, 88014), tuple(53441, 1659), tuple(7606, 35735), tuple(52971, 83457), tuple(77912, 97683), tuple(33195, 462), tuple(36642, 84826), tuple(14627, 39789), tuple(35158, 74576), tuple(31178, 3298), tuple(78999, 38000), tuple(58392, 70574), tuple(32797, 9393), tuple(31745, 73068), tuple(3463, 99157), tuple(85198, 99633), tuple(69136, 61700), tuple(90269, 56346), tuple(54888, 30161), tuple(69578, 67718), tuple(31362, 88940), tuple(72151, 69802), tuple(10518, 42128), tuple(10389, 85928), tuple(79024, 46427), tuple(75298, 320), tuple(61374, 92005), tuple(52693, 92872), tuple(90677, 97987), tuple(4977, 7002), tuple(34950, 40356), tuple(1286, 84570), tuple(83587, 44056), tuple(60303, 67073), tuple(90693, 54889), tuple(3665, 65556), tuple(36965, 91476), tuple(36018, 1114), tuple(64173, 73176), tuple(74375, 37973), tuple(40226, 4894), tuple(15708, 44097), tuple(58497, 62654), tuple(88190, 8945), tuple(89623, 42745), tuple(34666, 46515), tuple(69908, 60462), tuple(85257, 89711), tuple(95343, 25345), tuple(9671, 68154), tuple(43560, 12783), tuple(56946, 86701), tuple(97027, 16286), tuple(73465, 82933), tuple(60864, 98196), tuple(65681, 78455), tuple(95949, 98824), tuple(60427, 79639), tuple(62125, 96638), tuple(44349, 55436), tuple(23889, 98287), tuple(7982, 57100), tuple(89134, 62354), tuple(90345, 13136), tuple(87117, 55670), tuple(87142, 56737), tuple(12166, 62622), tuple(25757, 83242), tuple(22839, 70866), tuple(55230, 87710), tuple(52836, 58660), tuple(52001, 11928), tuple(32300, 43940), tuple(82815, 15966), tuple(25995, 35077), tuple(85590, 71892), tuple(65700, 97621), tuple(93120, 45889), tuple(39090, 18624), tuple(40711, 54078), tuple(21512, 71018), tuple(84273, 83224), tuple(94455, 11165), tuple(44762, 81935), tuple(32383, 12092), tuple(57681, 45595), tuple(34900, 10701), tuple(75918, 15671), tuple(80894, 47445), tuple(84887, 65029), tuple(20046, 53478), tuple(35117, 350), tuple(58605, 95757), tuple(41129, 70721), tuple(17956, 60019), tuple(92256, 31486), tuple(25628, 39061), tuple(46442, 95181), tuple(99796, 98961), tuple(84447, 67126), tuple(90905, 35020), tuple(44920, 85041), tuple(29355, 81130), tuple(27574, 74365), tuple(18795, 87608), tuple(9134, 94033), tuple(40788, 33406), tuple(66374, 27589), tuple(35828, 79467), tuple(63337, 21310), tuple(19850, 91859), tuple(8457, 46910), tuple(17247, 54352), + tuple(78157, 12984), tuple(19014, 95404), tuple(33696, 61297), tuple(84179, 86141), tuple(88420, 35793), tuple(56841, 54309), tuple(61086, 51639), tuple(51422, 42981), tuple(24495, 8959), tuple(44560, 17680), tuple(5010, 310), tuple(7658, 47071), tuple(99542, 84835), tuple(32524, 20855), tuple(74043, 44891), tuple(86735, 20535), tuple(73782, 59995), tuple(93939, 67476), tuple(3553, 2160), tuple(28263, 96116), tuple(43233, 84344), tuple(82394, 41116), tuple(94208, 54259), tuple(19293, 78307), tuple(97691, 89913), tuple(69180, 92822), tuple(54514, 17070), tuple(41565, 19577), tuple(56860, 57944), tuple(79429, 90334), tuple(14209, 63872), tuple(8193, 47375), tuple(84457, 5729), tuple(35499, 29880), tuple(71046, 96629), tuple(78320, 16678), tuple(52171, 9008), tuple(10285, 77600), tuple(89222, 56452), tuple(74877, 45130), tuple(45122, 7477), tuple(27680, 36119), tuple(53572, 67978), tuple(84553, 96126), tuple(79947, 45957), tuple(62290, 6001), tuple(24885, 66150), tuple(74756, 8350), tuple(19600, 26665), tuple(26140, 12798), tuple(346, 52401), tuple(55107, 64736), tuple(55227, 20192), tuple(5250, 75970), tuple(22597, 36117), tuple(46057, 6297), tuple(146, 34226), tuple(62101, 45872), tuple(50973, 81711), tuple(28437, 90316), tuple(87949, 33752), tuple(97761, 97260), tuple(33866, 10748), tuple(43546, 29031), tuple(94371, 94717), tuple(23676, 36834), tuple(78530, 40195), tuple(9449, 90868), tuple(4688, 18113), tuple(6478, 91149), tuple(5770, 53359), tuple(67467, 45123), tuple(99961, 85269), tuple(16771, 9423), tuple(86093, 12345), tuple(57781, 91310), tuple(64235, 75090), tuple(44983, 14518), tuple(97295, 86692), tuple(9084, 63091), tuple(95536, 58091), tuple(19196, 84870), tuple(30135, 5353), tuple(8031, 34065), tuple(30428, 11126), tuple(64190, 14178), tuple(31159, 97833), tuple(52514, 36312), tuple(39470, 95767), tuple(56521, 58481), tuple(67491, 58112), tuple(93348, 30378), tuple(68108, 71570), tuple(1098, 967), tuple(38546, 81282), tuple(56825, 65979), tuple(59069, 72390), tuple(2824, 13703), tuple(48333, 14500), tuple(9893, 25478), tuple(2911, 47477), tuple(58177, 26157), tuple(82958, 11140), tuple(29280, 90771), tuple(87961, 77195), tuple(41212, 31814), tuple(57596, 21467), tuple(95701, 96920), tuple(42264, 95301), tuple(40893, 490), tuple(85295, 66203), tuple(82996, 55114), tuple(7692, 97829), tuple(29833, 90468), tuple(11917, 11893), tuple(29516, 81375), tuple(89726, 44500), tuple(8932, 49236), tuple(46908, 11625), tuple(37562, 86013), tuple(77455, 10903), tuple(71128, 96631), tuple(14398, 25421), tuple(22273, 24791), tuple(53432, 89441), tuple(65639, 13703), tuple(87847, 91934), tuple(79196, 83398), tuple(93841, 8300), tuple(98217, 31103), tuple(74206, 10777), tuple(87556, 26040), tuple(3488, 46363), tuple(5052, 37977), tuple(13148, 84770), tuple(57802, 44741), tuple(52562, 89370), tuple(45417, 28092), tuple(10850, 53735), tuple(55528, 13265), tuple(49639, 60069), tuple(24297, 65409), tuple(17691, 74780), tuple(14056, 91384), tuple(26678, 79745), tuple(20819, 65318), tuple(5109, 36921), tuple(32429, 44351), tuple(49300, 87487), tuple(91490, 17942), tuple(91165, 36259), tuple(19889, 92478), tuple(32525, 24314), + tuple(32207, 12383), tuple(18946, 80847), tuple(26629, 99576), tuple(23663, 33753), tuple(78661, 43289), tuple(42971, 85652), tuple(13148, 37633), tuple(7460, 31621), tuple(7106, 19344), tuple(56623, 40597), tuple(3931, 46383), tuple(40928, 80864), tuple(54411, 42893), tuple(97994, 37208), tuple(98704, 34056), tuple(28221, 65071), tuple(17035, 74621), tuple(44980, 99037), tuple(74685, 40941), tuple(51689, 87959), tuple(1603, 88894), tuple(58816, 80911), tuple(6600, 88186), tuple(51598, 56572), tuple(94570, 53971), tuple(36829, 22411), tuple(78272, 19485), tuple(27782, 91187), tuple(50738, 34908), tuple(77246, 37199), tuple(54696, 25448), tuple(22518, 20075), tuple(93517, 9215), tuple(63893, 61738), tuple(1803, 66542), tuple(8740, 44384), tuple(50214, 2536), tuple(82978, 22366), tuple(30379, 1906), tuple(69739, 14688), tuple(32367, 37176), tuple(94639, 5870), tuple(28089, 44553), tuple(23425, 12581), tuple(55612, 25746), tuple(10872, 85235), tuple(78490, 47300), tuple(53808, 99715), tuple(73003, 81707), tuple(69544, 44704), tuple(49921, 45937), tuple(53055, 64486), tuple(29788, 41235), tuple(66977, 32399), tuple(14272, 19156), tuple(52628, 43512), tuple(84512, 95549), tuple(37407, 73000), tuple(97454, 5645), tuple(94560, 22177), tuple(43121, 24751), tuple(16392, 71632), tuple(57061, 95049), tuple(78509, 12622), tuple(19152, 31950), tuple(60772, 58980), tuple(80874, 81688), tuple(57277, 94240), tuple(72106, 83377), tuple(96685, 38772), tuple(67254, 25148), tuple(55927, 21049), tuple(60288, 62456), tuple(70931, 77751), tuple(79197, 16179), tuple(3655, 47431), tuple(46830, 73545), tuple(45050, 41379), tuple(27458, 17406), tuple(39099, 99237), tuple(67490, 80382), tuple(62723, 79115), tuple(8353, 32032), tuple(23488, 12738), tuple(4013, 67892), tuple(26464, 50462), tuple(35943, 94375), tuple(44186, 34987), tuple(60927, 88755), tuple(8465, 63630), tuple(66062, 34368), tuple(88036, 58046), tuple(58249, 81975), tuple(18237, 47105), tuple(6733, 82935), tuple(78749, 39033), tuple(15131, 26574), tuple(33524, 8929), tuple(41839, 16312), tuple(55673, 27094), tuple(49538, 11713), tuple(88371, 69776), tuple(94252, 13464), tuple(5832, 84375), tuple(89357, 64815), tuple(46801, 11748), tuple(30666, 81254), tuple(16789, 10599), tuple(42935, 98646), tuple(66143, 20772), tuple(44556, 23422), tuple(46018, 16312), tuple(22259, 77171), tuple(56983, 86832), tuple(49921, 22125), tuple(92296, 45486), tuple(69764, 34023), tuple(9637, 96817), tuple(51206, 30615), tuple(10348, 92983), tuple(14472, 99323), tuple(40262, 97192), tuple(2191, 68285), tuple(22924, 25679), tuple(5067, 66212), tuple(69487, 49838), tuple(20052, 16120), tuple(95935, 71293), tuple(1776, 51796), tuple(23090, 30667), tuple(52957, 44078), tuple(91342, 24546), tuple(50425, 89005), tuple(53426, 47583), tuple(6584, 10139), tuple(3118, 13516), tuple(55369, 99320), tuple(63349, 89873), tuple(64571, 74984), tuple(26517, 2840), tuple(33325, 27702), tuple(43660, 87008), tuple(25645, 63104), tuple(26144, 93808), tuple(38030, 8593), tuple(46594, 22518), tuple(17472, 60358), tuple(23471, 75904), tuple(64653, 25665), tuple(58930, 2800), tuple(9714, 21659), tuple(90877, 15172), tuple(24169, 33165), tuple(40301, 28982), tuple(5835, 58106), tuple(47425, 55922), tuple(85182, 8833), tuple(54791, 76061), tuple(43334, 95233), tuple(88895, 11611), tuple(67974, 99700), tuple(42359, 7619), tuple(46091, 3188), tuple(96126, 1150), tuple(67300, 70263), tuple(15504, 6792), tuple(43488, 51128), tuple(59882, 82061), tuple(53674, 82213), tuple(13942, 71867), tuple(37229, 44172), tuple(8234, 10116), tuple(63955, 93663), tuple(90556, 81422), tuple(36156, 23916), tuple(80004, 32883), tuple(97483, 91439), tuple(40380, 75895), tuple(49030, 13388), tuple(10112, 23706), tuple(12693, 54634), tuple(89114, 44239), tuple(79449, 97096), tuple(93945, 17715), tuple(84610, 91409), tuple(77676, 32755), tuple(96528, 43811), tuple(32771, 17368), tuple(72726, 51584), tuple(68373, 27912), tuple(13120, 2918), tuple(32440, 89244), tuple(94188, 42530), tuple(47136, 16569), tuple(38629, 72378), tuple(6704, 33393), tuple(29123, 2559), tuple(4782, 19801), tuple(67017, 24504), tuple(10924, 38797), tuple(8704, 22146), tuple(32103, 77336), tuple(38053, 7912), tuple(6562, 22610), tuple(27942, 63645), tuple(40426, 37003), tuple(21523, 64033), tuple(46299, 23083), tuple(48752, 46938), tuple(28350, 22135), tuple(14308, 14980), tuple(14573, 24398), tuple(7228, 37742), tuple(82025, 86225), tuple(53716, 36196), tuple(81985, 16387), tuple(57584, 81974), tuple(99131, 7574), tuple(62847, 67483), tuple(86114, 25787), tuple(53211, 78386), tuple(80778, 49571), tuple(32747, 39211), tuple(71223, 56413), tuple(60888, 54163), tuple(7192, 51136), tuple(53334, 59228), tuple(4421, 66662), tuple(33413, 84705), tuple(56666, 78956), tuple(61801, 42678), tuple(43053, 77774), tuple(63820, 28596), tuple(1077, 97015), tuple(64021, 64781), tuple(92706, 3502), tuple(10677, 85713), tuple(25226, 89936), tuple(72837, 6353), tuple(48761, 89256), tuple(65947, 66655), tuple(72098, 73523), tuple(90795, 85045), tuple(55030, 92320), tuple(55194, 86101), tuple(10745, 5734), tuple(88677, 87133), tuple(73661, 34366), tuple(45949, 27357), tuple(88662, 12417), tuple(8489, 13536), tuple(27549, 4543), tuple(92939, 3478), tuple(54350, 80071), tuple(18846, 12230), tuple(44026, 16272), tuple(61412, 29030), tuple(19174, 95986), tuple(95690, 96752), tuple(89204, 59178), tuple(88740, 16634), tuple(86216, 73138), tuple(78274, 75895), tuple(33616, 9671), tuple(34033, 95200), tuple(34068, 66630), tuple(86998, 11248), tuple(33926, 18414), tuple(70477, 34726), tuple(78159, 51516), tuple(39498, 51001), tuple(8129, 45722), tuple(80034, 74923), tuple(72313, 14607), tuple(24587, 66307), tuple(1705, 17417), tuple(72039, 30982), tuple(38633, 26195), tuple(28199, 39357), tuple(38581, 11807), tuple(86457, 96618), tuple(26962, 65955), tuple(91876, 59903), tuple(73754, 98220), tuple(52133, 25146), tuple(66110, 69603), tuple(1793, 33205), tuple(15034, 44701), tuple(51124, 76916), tuple(39534, 36662), tuple(25979, 69668), tuple(57384, 67311), tuple(18545, 60762), tuple(19046, 92399), tuple(38249, 4653), tuple(72527, 59270), tuple(33966, 37148), tuple(27590, 117), tuple(70374, 4742), tuple(16192, 75527), tuple(80174, 75518), tuple(48577, 98517), tuple(94414, 14445), tuple(67138, 13404), tuple(92294, 29477), tuple(20990, 61280), tuple(6082, 29420), tuple(43509, 34811), tuple(58769, 96326), tuple(47885, 53134), tuple(85917, 57373), tuple(64717, 50457), tuple(91239, 92881), tuple(76074, 79095), tuple(59275, 17799), tuple(75883, 62491), tuple(39406, 78272), tuple(70235, 10333), tuple(42309, 18408), tuple(53739, 27090), tuple(98800, 48751), tuple(99156, 65930), tuple(6271, 73084), tuple(83758, 55709), tuple(76940, 71591), tuple(37834, 27418), tuple(46486, 84091), tuple(82677, 5668), tuple(55483, 14400), tuple(64749, 41246), tuple(56980, 81320), tuple(46656, 22155), tuple(85260, 3342), tuple(56103, 57517), tuple(15434, 77526), tuple(90927, 99005), tuple(30948, 35441), tuple(75700, 35428), tuple(46759, 50091), tuple(58497, 88465), tuple(4893, 48180), tuple(69671, 63922), tuple(53917, 42248), tuple(49692, 75520), tuple(70709, 69868), tuple(54172, 66609), tuple(61142, 39487), tuple(70390, 96503), tuple(70529, 96890), tuple(50848, 54706), tuple(62574, 78585), tuple(40976, 40546), tuple(61448, 25487), tuple(58813, 79694), tuple(7978, 46692), tuple(84810, 47407), tuple(93301, 86788), tuple(63513, 40417), tuple(50816, 14830), tuple(40051, 22510), tuple(58231, 10222), tuple(22087, 58099), tuple(9757, 76220), tuple(75890, 86576), tuple(78978, 41357), tuple(93283, 24850), tuple(97099, 31675), tuple(73642, 95617), tuple(12154, 57246), tuple(67695, 45009), tuple(24512, 19561), tuple(32912, 57975), tuple(67101, 86402), tuple(97078, 61699), tuple(35404, 84433), tuple(18387, 5574), tuple(1180, 56954), tuple(31887, 11863), tuple(35632, 74282), tuple(97946, 71382), tuple(6358, 42197), tuple(3005, 63694), tuple(33955, 21482), tuple(81930, 4333), tuple(91114, 65927), tuple(47204, 48539), tuple(79942, 34686), tuple(77140, 46671), tuple(24959, 43593), tuple(26774, 12024), tuple(17931, 38033), tuple(18367, 18250), tuple(40538, 12655), tuple(10024, 2337), tuple(13012, 93366), tuple(33214, 99392), tuple(48339, 83815), tuple(2573, 98741), tuple(82426, 99315), tuple(29161, 8227), tuple(75276, 43314), tuple(11764, 85873), tuple(67647, 12433), tuple(31911, 90471), tuple(9087, 22041), tuple(10617, 3373), tuple(82133, 44117), tuple(31131, 3256), tuple(99076, 13086), tuple(96657, 56552), tuple(23455, 55109), tuple(5669, 90191), tuple(63460, 25790), tuple(85510, 22302), tuple(12906, 98397), tuple(18329, 44604), tuple(15748, 14050), tuple(21155, 62893), tuple(37100, 83871), tuple(25674, 92250), tuple(53171, 44750), tuple(46127, 54563), tuple(44166, 66056), tuple(64908, 74534), tuple(78505, 79266), tuple(93470, 55884), tuple(11989, 62985), tuple(37465, 50339), tuple(22878, 79000), tuple(95605, 98821), tuple(99575, 49974), tuple(41632, 45612), tuple(12260, 36028), tuple(50671, 19437), tuple(91453, 49879), tuple(12875, 83736), tuple(64102, 71173), tuple(48782, 46491), tuple(83745, 47638), tuple(88148, 76992), tuple(48165, 43667), tuple(92415, 18463), tuple(21414, 88902), tuple(78393, 87130), tuple(98155, 18890), tuple(58021, 92700), tuple(44621, 68966), tuple(7039, 68126), tuple(56673, 25907), tuple(33837, 57344), tuple(87382, 7033), tuple(67819, 29142), tuple(15461, 61937), tuple(5731, 90942), tuple(95838, 74174), tuple(82453, 30836), tuple(77643, 4537), tuple(70433, 44347), tuple(31774, 69412), tuple(72181, 53595), tuple(92692, 68594), tuple(18251, 47790), tuple(58848, 6565), tuple(1826, 80845), tuple(44441, 73811), tuple(16752, 29291), tuple(96792, 64536), tuple(18171, 37623), tuple(55235, 61816), tuple(20040, 83863), tuple(32432, 85684), tuple(4782, 77614), tuple(63342, 59121), tuple(38926, 85577), tuple(84429, 6450), tuple(95889, 92209), tuple(79472, 39518), tuple(30545, 68613), tuple(16797, 18913), + tuple(57243, 45824), tuple(8263, 41386), tuple(44982, 25137), tuple(51794, 44064), tuple(40504, 59817), tuple(11905, 14718), tuple(68061, 89924), tuple(43733, 93778), tuple(16215, 98598), tuple(84708, 29188), tuple(63541, 86310), tuple(44070, 14118), tuple(289, 75590), tuple(45870, 49980), tuple(18753, 17336), tuple(24732, 68239), tuple(27871, 52742), tuple(14696, 68693), tuple(99672, 72079), tuple(71245, 39241), tuple(67389, 16601), tuple(21752, 72806), tuple(96913, 30350), tuple(54185, 84992), tuple(57931, 11103), tuple(48704, 71007), tuple(99423, 36848), tuple(41315, 42065), tuple(87326, 72929), tuple(25384, 89587), tuple(59014, 60053), tuple(62267, 54542), tuple(12610, 32715), tuple(68975, 19985), tuple(44486, 69639), tuple(82302, 6338), tuple(63215, 87639), tuple(96904, 81511), tuple(69636, 10922), tuple(88663, 59485), tuple(59135, 3754), tuple(75988, 60625), tuple(64120, 45694), tuple(70324, 80636), tuple(15785, 77984), tuple(51352, 57485), tuple(2805, 39888), tuple(74622, 13408), tuple(20818, 1699), tuple(52553, 75450), tuple(10931, 27164), tuple(25541, 66990), tuple(40600, 10237), tuple(37780, 18746), tuple(58451, 29777), tuple(99485, 87814), tuple(35490, 54578), tuple(27880, 7151), tuple(5621, 11448), tuple(16276, 60088), tuple(80061, 79868), tuple(79495, 85729), tuple(5786, 28078), tuple(7505, 68947), tuple(3754, 73982), tuple(83095, 13882), tuple(13625, 48305), tuple(65566, 46143), tuple(28436, 47606), tuple(41318, 73446), tuple(70295, 17014), tuple(70052, 53076), tuple(75069, 22060), tuple(38749, 80432), tuple(5609, 18240), tuple(73251, 78035), tuple(44085, 34842), tuple(64413, 19036), tuple(76628, 13364), tuple(77620, 44200), tuple(51408, 58569), tuple(63273, 12356), tuple(73860, 29016), tuple(1540, 65413), tuple(4154, 73503), tuple(8522, 57385), tuple(24021, 60714), tuple(53183, 28103), tuple(9298, 20623), tuple(35572, 72750), tuple(20062, 88412), tuple(53090, 54056), tuple(75500, 24693), tuple(63463, 23751), tuple(17602, 18766), tuple(36512, 54793), tuple(83806, 80218), tuple(13965, 576), tuple(18995, 7730), tuple(28727, 8773), tuple(90604, 21980), tuple(89414, 40461), tuple(61108, 29240), tuple(30381, 96560), tuple(32285, 26545), tuple(38149, 85647), tuple(51471, 24524), tuple(42153, 32188), tuple(12747, 84522), tuple(96507, 99501), tuple(39908, 54706), tuple(37524, 46449), tuple(98286, 72361), tuple(32855, 96561), tuple(67644, 50836), tuple(73095, 33548), tuple(3239, 57909), tuple(59527, 51138), tuple(61862, 15544), tuple(84048, 4884), tuple(17440, 53732), tuple(3534, 42048), tuple(66894, 37347), tuple(34323, 11139), tuple(64183, 38919), tuple(87672, 76883), tuple(99127, 44364), tuple(41417, 86134), tuple(51181, 7902), tuple(55456, 98977), tuple(52953, 51347), tuple(54164, 45398), tuple(36894, 60364), tuple(16911, 44245), tuple(92377, 11522), tuple(22925, 43609), tuple(52979, 70952), tuple(98059, 42838), tuple(18178, 76534), tuple(8036, 92888), tuple(88589, 19468), tuple(35901, 19860), tuple(65686, 87008), tuple(32387, 43037), tuple(87245, 20229), tuple(316, 46084), tuple(4111, 2785), tuple(89736, 56537), tuple(5724, 30008), tuple(82292, 28294), tuple(38892, 21915), tuple(51202, 50642), tuple(99865, 33343), + tuple(95804, 70967), tuple(12070, 43458), tuple(6220, 56015), tuple(74329, 56204), tuple(21399, 75467), tuple(88203, 43858), tuple(38704, 47055), tuple(19362, 60219), tuple(14634, 72618), tuple(41448, 6543), tuple(87651, 18534), tuple(34327, 75539), tuple(3541, 25818), tuple(20404, 80339), tuple(44944, 55964), tuple(45651, 49213), tuple(65846, 85412), tuple(51675, 22001), tuple(74879, 97711), tuple(32455, 26455), tuple(5056, 69437), tuple(46238, 41978), tuple(11156, 81627), tuple(40029, 70165), tuple(87185, 7409), tuple(53171, 90875), tuple(38789, 40512), tuple(61386, 8745), tuple(81736, 4812), tuple(71196, 92427), tuple(13554, 32085), tuple(41154, 59222), tuple(58043, 66198), tuple(21838, 40563), tuple(33897, 65211), tuple(28903, 30143), tuple(21409, 47493), tuple(26059, 95417), tuple(73900, 48368), tuple(18774, 30490), tuple(73012, 44125), tuple(58456, 61155), tuple(60554, 28996), tuple(8827, 36373), tuple(30404, 97981), tuple(30881, 46098), tuple(13258, 80907), tuple(72012, 13691), tuple(23651, 30968), tuple(2969, 50097), tuple(33733, 79191), tuple(10223, 90306), tuple(98149, 11670), tuple(45547, 25317), tuple(77139, 63654), tuple(55598, 73329), tuple(22887, 43966), tuple(73233, 39855), tuple(71344, 61217), tuple(4060, 79956), tuple(73925, 30838), tuple(7635, 14926), tuple(53804, 37839), tuple(69335, 59926), tuple(34807, 32895), tuple(78509, 73239), tuple(36494, 91580), tuple(66250, 40428), tuple(92495, 92721), tuple(13503, 8974), tuple(1533, 7446), tuple(84074, 88477), tuple(17188, 48916), tuple(88681, 88849), tuple(96162, 65641), tuple(71517, 35507), tuple(53803, 30244), tuple(54097, 55628), tuple(58528, 34100), tuple(15910, 46623), tuple(89311, 69918), tuple(34706, 33424), tuple(52525, 7174), tuple(36409, 22829), tuple(16575, 59807), tuple(26247, 36935), tuple(58999, 98875), tuple(73380, 90788), tuple(11800, 64690), tuple(71312, 64235), tuple(35708, 76049), tuple(65621, 59223), tuple(94220, 15399), tuple(32073, 46262), tuple(38017, 57787), tuple(85453, 57087), tuple(57354, 18076), tuple(15620, 9885), tuple(54585, 11470), tuple(86532, 11214), tuple(90392, 36339), tuple(41222, 63156), tuple(41956, 46957), tuple(11257, 59047), tuple(7904, 91165), tuple(33757, 89829), tuple(36561, 76484), tuple(24535, 70034), tuple(58932, 52035), tuple(44009, 86647), tuple(21710, 66730), tuple(19750, 19959), tuple(12488, 23120), tuple(3857, 92163), tuple(1605, 57740), tuple(9460, 45243), tuple(63737, 91447), tuple(97379, 73859), tuple(24109, 75972), tuple(88375, 99620), tuple(11175, 97854), tuple(78504, 60445), tuple(63669, 89304), tuple(37661, 27971), tuple(56797, 37186), tuple(49704, 37165), tuple(58568, 72097), tuple(66051, 28778), tuple(37075, 75947), tuple(38543, 51647), tuple(75077, 39030), tuple(77878, 37117), tuple(75140, 60743), tuple(18900, 6472), tuple(48578, 88913), tuple(26467, 92904), tuple(55006, 10313), tuple(20860, 923), tuple(96408, 80209), tuple(68515, 29809), tuple(11686, 36655), tuple(37673, 68001), tuple(71190, 98343), tuple(9866, 26660), tuple(52912, 14692), tuple(71503, 17364), tuple(22754, 80041), tuple(20097, 45934), tuple(85767, 40813), tuple(8326, 21813), tuple(71122, 42467), tuple(11149, 52952), tuple(99239, 73844), tuple(46925, 31154), tuple(4219, 6051), tuple(4349, 18054), tuple(57355, 88606), tuple(79627, 89547), tuple(35391, 52278), tuple(7921, 5095), tuple(84435, 58925), tuple(23209, 80993), tuple(6392, 64395), tuple(26778, 62624), tuple(4484, 76470), tuple(85595, 21682), tuple(43801, 57907), tuple(21360, 55981), tuple(90765, 19734), tuple(59965, 32734), tuple(21698, 54400), tuple(3202, 51301), tuple(50398, 27389), tuple(11195, 59086), tuple(80810, 68107), tuple(80246, 86109), tuple(8264, 67640), tuple(45129, 49779), tuple(3741, 39591), tuple(92596, 44524), tuple(61323, 7060), tuple(85650, 4974), tuple(57933, 64074), tuple(82675, 91822), tuple(88157, 69528), tuple(15295, 64351), tuple(38370, 6787), tuple(32886, 73349), tuple(64461, 91272), tuple(61885, 12074), tuple(66868, 69079), tuple(97050, 88063), tuple(17423, 65097), tuple(98155, 52111), tuple(30406, 53315), tuple(77111, 31673), tuple(88833, 29556), tuple(17834, 49818), tuple(93996, 77258), tuple(27859, 8227), tuple(50422, 99996), tuple(72852, 25549), tuple(50960, 30223), tuple(26847, 86597), tuple(57065, 75358), tuple(17500, 59618), tuple(71963, 7160), tuple(82261, 26132), tuple(57310, 33759), tuple(74850, 36130), tuple(80679, 12358), tuple(25146, 69695), tuple(51169, 36809), tuple(34345, 42666), tuple(25529, 79964), tuple(16957, 2056), tuple(11384, 73397), tuple(87339, 16821), tuple(36838, 38944), tuple(33609, 29887), tuple(81930, 27309), tuple(85427, 98289), tuple(56553, 34578), tuple(28022, 64719), tuple(48137, 50016), tuple(64006, 99858), tuple(96683, 2581), tuple(64215, 63294), tuple(80480, 59268), tuple(37552, 74897), tuple(68924, 33400), tuple(12320, 3485), tuple(46342, 47198), tuple(10486, 84214), tuple(10637, 37979), tuple(82102, 8674), tuple(45272, 18937), tuple(85813, 9828), tuple(42952, 81515), tuple(36109, 60929), tuple(49908, 81308), tuple(77480, 79720), tuple(47309, 93694), tuple(92133, 64187), tuple(59797, 76215), tuple(57715, 88948), tuple(34251, 75387), tuple(98032, 9443), tuple(82908, 50870), tuple(36667, 90760), tuple(11497, 70446), tuple(55263, 9996), tuple(95530, 15624), tuple(61374, 49255), tuple(47466, 11077), tuple(42810, 44265), tuple(78332, 84057), tuple(95033, 41926), tuple(24384, 51662), tuple(47128, 47040), tuple(14895, 37303), tuple(6995, 23571), tuple(30773, 73534), tuple(69169, 94373), tuple(29022, 92890), tuple(46660, 69109), tuple(39814, 75285), tuple(57314, 90534), tuple(63237, 59127), tuple(69470, 9152), tuple(71565, 81652), tuple(42371, 77809), tuple(66206, 24490), tuple(53101, 69390), tuple(56648, 69898), tuple(25813, 5835), tuple(82233, 2630), tuple(8386, 52693), tuple(85310, 85937), tuple(87403, 83920), tuple(290, 80083), tuple(9562, 46994), tuple(15806, 73988), tuple(54094, 2149), tuple(6324, 79545), tuple(97932, 65717), tuple(33267, 33685), tuple(49599, 23793), tuple(97471, 77574), tuple(36005, 7441), tuple(80654, 94174), tuple(63236, 7016), tuple(93694, 87168), tuple(14169, 63653), tuple(79452, 21186), tuple(6879, 93530), tuple(44992, 4491), tuple(55716, 78989), tuple(81229, 83954), tuple(63203, 84403), tuple(50575, 77597), tuple(97412, 87338), tuple(26386, 54156), tuple(35465, 54200), tuple(42993, 1096), tuple(19501, 87529), tuple(23563, 89524), tuple(85276, 24678), tuple(28839, 73007), tuple(54050, 80260), tuple(41862, 45747), tuple(45532, 4796), tuple(59766, 78513), tuple(42873, 27842), tuple(14066, 14788), tuple(42226, 19459), tuple(66168, 97420), tuple(73275, 78209), tuple(755, 75149), tuple(10424, 17589), tuple(59752, 5362), tuple(16612, 48631), tuple(97558, 55845), tuple(77602, 94389), tuple(17033, 91672), tuple(81010, 47646), tuple(8792, 74197), tuple(62409, 86387), tuple(23940, 73202), tuple(74326, 93461), tuple(99700, 28417), tuple(12373, 31471), tuple(19780, 82462), tuple(84100, 66414), tuple(33739, 27879), tuple(65869, 19590), tuple(53768, 80619), tuple(7632, 72890), tuple(13016, 2777), tuple(28709, 51472), tuple(64803, 48135), tuple(2016, 6998), tuple(32601, 51082), tuple(58866, 23304), tuple(87096, 82571), tuple(54567, 12251), tuple(60574, 64548), tuple(32946, 20929), tuple(95087, 91320), tuple(32702, 51680), tuple(71934, 62082), tuple(7598, 45620), tuple(25713, 83796), tuple(22509, 59083), tuple(99368, 66914), tuple(22928, 984), tuple(74309, 35226), tuple(38296, 93051), tuple(28362, 36277), tuple(81873, 9185), tuple(79122, 50838), tuple(31448, 35443), tuple(25046, 97283), tuple(51849, 76572), tuple(83722, 31233), tuple(75316, 70515), tuple(67359, 69686), tuple(80368, 87585), tuple(51714, 92098), tuple(5772, 72330), tuple(96652, 97645), tuple(10531, 86149), tuple(4378, 65728), tuple(80551, 93867), tuple(46660, 8809), tuple(83039, 80501), tuple(38249, 12848), tuple(48679, 54119), tuple(77295, 29795), tuple(65702, 69250), tuple(87195, 3131), tuple(26611, 29868), tuple(88164, 4187), tuple(42078, 63303), tuple(46501, 95311), tuple(7063, 38185), tuple(94346, 35287), tuple(75324, 16799), tuple(49000, 44453), tuple(309, 54608), tuple(16024, 77175), tuple(75300, 29332), tuple(45928, 81737), tuple(28049, 97890), tuple(87565, 86417), tuple(25253, 22620), tuple(77837, 33503), tuple(19857, 67728), tuple(6316, 72927), tuple(33001, 15626), tuple(79133, 25621), tuple(23468, 29945), tuple(10889, 13574), tuple(84771, 66067), tuple(22974, 59756), tuple(25169, 32080), tuple(2763, 69489), tuple(95845, 1960), tuple(8989, 53327), tuple(68781, 39147), tuple(90201, 88456), tuple(59526, 93326), tuple(52344, 75391), tuple(85184, 31369), tuple(94710, 93662), tuple(54889, 49149), tuple(29952, 55792), tuple(33265, 8947), tuple(44096, 26042), tuple(56712, 53763), tuple(55427, 14296), tuple(8731, 11564), tuple(62987, 83), tuple(53575, 58165), tuple(63627, 82316), tuple(50117, 30149), tuple(20026, 57072), tuple(83807, 29051), tuple(77431, 60892), tuple(89918, 41830), tuple(80530, 98080), tuple(98699, 33390), tuple(86743, 62505), tuple(22963, 23417), tuple(76581, 89370), tuple(3725, 51427), tuple(26360, 93305), tuple(65141, 27209), tuple(7445, 52852), tuple(56158, 4399), tuple(87204, 7475), tuple(82189, 11735), tuple(62875, 99644), tuple(94415, 59283), tuple(79059, 42636), tuple(27095, 24606), tuple(22228, 41626), tuple(15766, 33419), tuple(36090, 64191), tuple(33858, 28804), tuple(40697, 70965), tuple(1895, 48621), tuple(55078, 8926), tuple(84940, 99519), tuple(50750, 83936), tuple(63108, 59256), tuple(88855, 52935), tuple(62544, 38446), tuple(76256, 21365), tuple(86161, 70307), tuple(9247, 80836), tuple(91204, 88378), tuple(88362, 91302), tuple(69563, 58603), tuple(76583, 5971), tuple(59824, 38885), tuple(40338, 61292), tuple(99653, 64086), tuple(52198, 77598), tuple(19667, 6), tuple(30378, 41690), tuple(5130, 21465), tuple(32633, 80628), tuple(69869, 59610), tuple(30453, 13017), tuple(59836, 37885), tuple(58131, 42797), tuple(3428, 5984), tuple(17299, 13377), tuple(68491, 26265), + tuple(75600, 36301), tuple(79469, 65256), tuple(98438, 92022), tuple(40135, 69628), tuple(52373, 11613), tuple(12460, 96481), tuple(36740, 9873), tuple(92746, 96113), tuple(32532, 75810), tuple(45871, 37825), tuple(13323, 92457), tuple(11853, 716), tuple(59161, 91872), tuple(33609, 76950), tuple(50145, 9040), tuple(82818, 64780), tuple(92700, 31810), tuple(5745, 30311), tuple(19252, 34721), tuple(91678, 50602), tuple(48847, 98284), tuple(55640, 96281), tuple(60726, 42098), tuple(4494, 48219), tuple(61428, 76363), tuple(91534, 87454), tuple(73201, 9683), tuple(72379, 68604), tuple(30607, 71891), tuple(71963, 41250), tuple(17585, 79804), tuple(64529, 84544), tuple(44429, 46924), tuple(30658, 76431), tuple(18422, 23472), tuple(88171, 11830), tuple(66762, 7895), tuple(74476, 53181), tuple(15386, 51972), tuple(55536, 25039), tuple(68166, 15362), tuple(24986, 96477), tuple(88289, 76764), tuple(48193, 92905), tuple(95456, 25805), tuple(78131, 37308), tuple(32236, 81885), tuple(3083, 33218), tuple(29652, 41185), tuple(42417, 13339), tuple(71362, 33608), tuple(25475, 24287), tuple(20460, 82673), tuple(94769, 76462), tuple(12527, 82290), tuple(21183, 45096), tuple(20544, 30257), tuple(69721, 12886), tuple(4, 36149), tuple(23696, 29088), tuple(86144, 92852), tuple(66152, 22322), tuple(22307, 63335), tuple(25128, 35257), tuple(11046, 4279), tuple(32665, 25699), tuple(28784, 44818), tuple(59793, 40459), tuple(13846, 39333), tuple(59816, 7467), tuple(40106, 36228), tuple(13565, 33667), tuple(17482, 80138), tuple(37698, 95869), tuple(16491, 96398), tuple(53057, 48448), tuple(71592, 23507), tuple(98947, 62014), tuple(85328, 91232), tuple(94951, 11033), tuple(38509, 57252), tuple(70111, 63297), tuple(36914, 97310), tuple(86662, 26580), tuple(36754, 49831), tuple(35316, 42861), tuple(49326, 47462), tuple(47854, 49167), tuple(61206, 69078), tuple(67416, 3064), tuple(33631, 27193), tuple(56786, 41757), tuple(14000, 63627), tuple(98455, 72204), tuple(11796, 3153), tuple(49366, 6099), tuple(16114, 6729), tuple(59942, 41512), tuple(85308, 60723), tuple(60186, 8930), tuple(28450, 20028), tuple(54132, 40793), tuple(20190, 39153), tuple(91793, 59468), tuple(48855, 49249), tuple(3252, 88308), tuple(55024, 19544), tuple(47999, 98668), tuple(3625, 66538), tuple(27774, 17048), tuple(49182, 25298), tuple(10689, 72768), tuple(64034, 38635), tuple(23327, 65875), tuple(18376, 42416), tuple(15686, 35974), tuple(22283, 56738), tuple(14419, 36171), tuple(397, 11730), tuple(50136, 7806), tuple(37842, 47683), tuple(606, 5298), tuple(66652, 8471), tuple(23268, 88344), tuple(8181, 42348), tuple(30015, 82155), tuple(65670, 4409), tuple(29161, 1269), tuple(62267, 51181), tuple(38076, 3852), tuple(14048, 61904), tuple(6132, 3284), tuple(22486, 26772), tuple(76678, 2511), tuple(16212, 13228), tuple(51402, 46487), tuple(99360, 11669), tuple(36934, 58173), tuple(71427, 76232), tuple(14509, 22573), tuple(98403, 76905), tuple(24839, 32100), tuple(71097, 7056), tuple(47286, 70888), tuple(90192, 33568), tuple(38798, 54148), tuple(20350, 66499), tuple(93010, 48622), tuple(13510, 34716), tuple(92779, 14508), tuple(57010, 91250), tuple(25212, 10989), tuple(65459, 91132), + tuple(66251, 59146), tuple(28920, 29336), tuple(86273, 50897), tuple(81311, 53009), tuple(22278, 85352), tuple(54231, 26356), tuple(94250, 51117), tuple(21152, 38875), tuple(39286, 22339), tuple(10290, 37852), tuple(43426, 20385), tuple(13603, 2341), tuple(2314, 12288), tuple(48785, 80096), tuple(16762, 92809), tuple(1689, 16006), tuple(46828, 44433), tuple(58147, 68612), tuple(31702, 34921), tuple(23807, 72511), tuple(63437, 35834), tuple(40643, 62303), tuple(78198, 57748), tuple(11496, 43030), tuple(91150, 85333), tuple(91817, 95369), tuple(1792, 59975), tuple(14816, 41573), tuple(9355, 32450), tuple(77243, 5352), tuple(17681, 11128), tuple(69700, 89110), tuple(37695, 98303), tuple(23160, 29924), tuple(83829, 29122), tuple(13009, 81770), tuple(64481, 60303), tuple(6842, 78532), tuple(16282, 32405), tuple(14204, 67463), tuple(41795, 83324), tuple(98134, 38132), tuple(93686, 89418), tuple(83031, 18065), tuple(96431, 28312), tuple(15488, 90870), tuple(90914, 35142), tuple(96174, 98411), tuple(93075, 61533), tuple(47394, 30134), tuple(46309, 98014), tuple(8574, 38881), tuple(42376, 78153), tuple(45938, 95700), tuple(14026, 14059), tuple(94138, 70460), tuple(62882, 3321), tuple(52628, 25566), tuple(42145, 97919), tuple(57580, 8897), tuple(1766, 74887), tuple(68391, 51311), tuple(16485, 36095), tuple(55867, 988), tuple(34600, 46771), tuple(35786, 23210), tuple(78683, 62604), tuple(11002, 87427), tuple(29747, 6771), tuple(53803, 50526), tuple(52691, 75371), tuple(58028, 36198), tuple(98041, 28071), tuple(81822, 4121), tuple(90995, 93843), tuple(3709, 74313), tuple(23318, 28167), tuple(60162, 87145), tuple(53243, 31382), tuple(69762, 54059), tuple(25151, 95865), tuple(55550, 62947), tuple(45463, 8036), tuple(59949, 91675), tuple(55331, 79612), tuple(13806, 57517), tuple(41328, 94361), tuple(8388, 210), tuple(43458, 1327), tuple(16416, 50975), tuple(64370, 86524), tuple(97121, 65142), tuple(82878, 64545), tuple(58547, 33372), tuple(67494, 4130), tuple(59446, 79185), tuple(83812, 58833), tuple(32172, 93730), tuple(10095, 30319), tuple(94135, 92795), tuple(64893, 12870), tuple(14634, 70083), tuple(23344, 42836), tuple(19624, 29135), tuple(28755, 57738), tuple(58401, 49863), tuple(76809, 91787), tuple(51952, 33167), tuple(31717, 78538), tuple(64811, 55131), tuple(61969, 12339), tuple(4900, 48310), tuple(67609, 55369), tuple(37333, 37245), tuple(91492, 19704), tuple(77592, 62200), tuple(1017, 41815), tuple(41362, 13627), tuple(46703, 92040), tuple(4664, 46637), tuple(25430, 87837), tuple(10270, 32932), tuple(46025, 34792), tuple(80621, 38362), tuple(79949, 31518), tuple(77767, 59212), tuple(11080, 69948), tuple(17376, 92279), tuple(73871, 86715), tuple(83524, 21178), tuple(94368, 61971), tuple(11262, 30062), tuple(12840, 52656), tuple(15300, 64176), tuple(70094, 42565), tuple(84503, 66968), tuple(65824, 63349), tuple(74306, 82791), tuple(85701, 1655), tuple(25190, 70557), tuple(82208, 58145), tuple(97669, 92489), tuple(62730, 52924), tuple(46970, 15748), tuple(71217, 57505), tuple(57336, 87380), tuple(13982, 71979), tuple(55899, 1192), tuple(6890, 69297), tuple(39849, 72896), tuple(60213, 22499), tuple(53820, 79877), tuple(61389, 24954), tuple(1021, 81047), tuple(95389, 90605), tuple(8590, 26855), tuple(92881, 46825), tuple(59567, 91455), tuple(87297, 1567), tuple(86333, 82913), tuple(16285, 32370), tuple(38900, 77251), tuple(96301, 92302), tuple(2799, 91579), tuple(59757, 56681), tuple(49229, 38404), tuple(16880, 51290), tuple(38700, 80456), tuple(51440, 32556), tuple(4507, 83325), tuple(29924, 40923), tuple(9937, 58356), tuple(70895, 52611), tuple(80488, 49196), tuple(93118, 6112), tuple(44058, 20923), tuple(70808, 72928), tuple(78269, 76351), tuple(81081, 63186), tuple(12406, 50247), tuple(91769, 37875), tuple(36197, 11434), tuple(72225, 93141), tuple(59295, 54160), tuple(39342, 10117), tuple(12920, 23240), tuple(91877, 61524), tuple(84807, 5431), tuple(63163, 52152), tuple(90320, 97456), tuple(14899, 12941), tuple(90079, 98004), tuple(46096, 68208), tuple(12176, 72405), tuple(28451, 61964), tuple(89254, 1676), tuple(76242, 5438), tuple(29756, 92658), tuple(14855, 41944), tuple(1519, 65495), tuple(74052, 65006), tuple(1075, 31521), tuple(84877, 98988), tuple(91426, 69442), tuple(39694, 43391), tuple(68328, 3447), tuple(50508, 61610), tuple(30890, 18792), tuple(60706, 87518), tuple(6692, 83260), tuple(92044, 79399), tuple(86846, 53543), tuple(28606, 61656), tuple(35449, 52965), tuple(43421, 13117), tuple(67404, 55238), tuple(80817, 79927), tuple(8908, 46083), tuple(22583, 19705), tuple(13, 25509), tuple(79771, 21210), tuple(42719, 19320), tuple(94091, 35389), tuple(95995, 42652), tuple(6417, 13464), tuple(22290, 34089), tuple(27119, 33408), tuple(7, 68019), tuple(55405, 50766), tuple(6331, 50009), tuple(33, 48235), tuple(3162, 85313), tuple(25897, 91775), tuple(30813, 83408), tuple(36062, 46449), tuple(78820, 78894), tuple(92054, 23008), tuple(10637, 4237), tuple(90702, 62678), tuple(80427, 98641), tuple(20834, 48068), tuple(74443, 29196), tuple(76088, 91823), tuple(39151, 48574), tuple(54050, 5374), tuple(60643, 1979), tuple(4535, 95086), tuple(82101, 67586), tuple(55746, 92488), tuple(88192, 22615), tuple(93282, 87547), tuple(37804, 61180), tuple(13445, 56654), tuple(38913, 10130), tuple(23472, 83441), tuple(94125, 56393), tuple(2967, 25078), tuple(76652, 84599), tuple(3586, 83503), tuple(46272, 62119), tuple(26002, 55790), tuple(75085, 55875), tuple(73786, 22608), tuple(63101, 59758), tuple(9688, 11910), tuple(54041, 38376), tuple(75595, 95722), tuple(36047, 59518), tuple(55041, 69102), tuple(42836, 48225), tuple(30046, 61157), tuple(60608, 94951), tuple(80257, 70300), tuple(40282, 67847), tuple(90735, 56299), tuple(82814, 89675), tuple(2998, 52357), tuple(86333, 5088), tuple(3414, 67855), tuple(28134, 64041), tuple(56871, 38384), tuple(51335, 28574), tuple(73451, 40395), tuple(59696, 49729), tuple(73379, 78187), tuple(67561, 79682), tuple(66114, 9153), tuple(4613, 41137), tuple(96832, 77637), tuple(64216, 22050), tuple(69871, 69883), tuple(78030, 8142), tuple(88000, 98796), tuple(24965, 60211), tuple(61727, 82326), tuple(64623, 21387), tuple(27307, 39907), tuple(47314, 29509), tuple(14676, 73902), tuple(48864, 28948), tuple(15974, 66359), tuple(68154, 2013), tuple(44016, 51609), tuple(95421, 89481), tuple(39985, 22127), tuple(88096, 18483), tuple(18539, 98797), tuple(83613, 26308), tuple(93997, 84284), tuple(35958, 46289), tuple(79263, 50800), tuple(4873, 92142), tuple(69509, 97567), tuple(17733, 9050), tuple(14632, 79901), tuple(94211, 83353), tuple(72112, 79110), tuple(13974, 83858), tuple(76735, 38529), tuple(67084, 67183), tuple(97827, 95135), tuple(55771, 88062), tuple(94630, 45565), tuple(20922, 85088), tuple(9180, 39703), tuple(86146, 21086), tuple(65955, 51015), tuple(77660, 57572), tuple(31577, 56429), tuple(52636, 56363), tuple(74365, 62124), tuple(60971, 13103), tuple(75234, 35529), tuple(26035, 39091), tuple(1145, 38641), tuple(24088, 49898), tuple(83610, 25448), tuple(8868, 32413), tuple(20877, 9306), tuple(40824, 73012), tuple(63105, 93113), tuple(21170, 21234), tuple(6564, 21210), tuple(27020, 39734), tuple(7431, 11643), tuple(56609, 23596), tuple(2023, 39429), tuple(63574, 88918), tuple(5188, 46658), tuple(3290, 24577), tuple(33271, 95049), tuple(72950, 94811), tuple(74876, 73210), tuple(6294, 42155), tuple(13767, 27366), tuple(86746, 54073), tuple(13001, 93376), tuple(13517, 96879), tuple(24380, 59684), tuple(49105, 55403), tuple(90533, 2745), tuple(48651, 23491), tuple(21409, 71113), tuple(7142, 71273), tuple(62952, 88544), tuple(82865, 10938), tuple(65089, 17672), tuple(43173, 47506), tuple(13708, 32610), tuple(26547, 77317), tuple(8676, 7117), tuple(62512, 39512), tuple(42233, 81433), tuple(45416, 63643), tuple(32392, 33632), tuple(83887, 402), tuple(53596, 54897), tuple(59707, 85005), tuple(96343, 20979), tuple(30344, 65226), tuple(34513, 24150), tuple(38715, 11205), tuple(20649, 7679), tuple(27948, 80080), tuple(77430, 49123), tuple(42437, 4729), tuple(90176, 34827), tuple(11039, 59573), tuple(47042, 38460), tuple(48086, 34987), tuple(65457, 5585), tuple(45956, 6198), tuple(22786, 24937), tuple(54287, 77515), tuple(12113, 84710), tuple(29543, 36869), tuple(8388, 60473), tuple(2771, 53359), tuple(35299, 64874), tuple(34132, 86266), tuple(37594, 64297), tuple(33390, 65843), tuple(53057, 46715), tuple(41874, 83250), tuple(26061, 30352), tuple(93351, 16651), tuple(25890, 16570), tuple(67403, 19546), tuple(8608, 51991), tuple(90616, 10018), tuple(46870, 54345), tuple(81919, 3577), tuple(99462, 3562), tuple(83193, 66098), tuple(92054, 70338), tuple(11383, 90149), tuple(42458, 2302), tuple(77850, 47281), tuple(62433, 4959), tuple(52392, 33711), tuple(2033, 4096), tuple(91460, 6795), tuple(27462, 76972), tuple(73087, 40511), tuple(42563, 5924), tuple(21819, 53017), tuple(31309, 62793), tuple(19798, 60725), tuple(90987, 77178), tuple(9949, 43079), tuple(13773, 40312), tuple(97080, 61184), tuple(59679, 78611), tuple(22361, 83227), tuple(70120, 95483), tuple(15529, 5672), tuple(25893, 99672), tuple(61722, 69201), tuple(55012, 37509), tuple(77999, 85866), tuple(77835, 83627), tuple(36792, 80218), tuple(54232, 58138), tuple(74593, 485), tuple(45698, 4153), tuple(96513, 738), tuple(33060, 53078), tuple(4439, 25097), tuple(62007, 64140), tuple(86128, 99499), tuple(66141, 4433), tuple(41032, 54527), tuple(59831, 61170), tuple(1189, 68117), tuple(63914, 26798), tuple(72045, 2999), tuple(6016, 42337), tuple(40611, 39747), tuple(88328, 44836), tuple(88939, 25365), tuple(40010, 43971), tuple(21419, 31975), tuple(27725, 21929), tuple(49459, 74763), tuple(32059, 96546), tuple(70985, 98967), tuple(33034, 36073), tuple(19600, 80524), tuple(59150, 56734), tuple(30433, 38795), tuple(55387, 47581), tuple(45109, 73833), tuple(59487, 5428), tuple(23140, 57618), tuple(36367, 31008), tuple(45983, 85518), tuple(28234, 83843), tuple(73005, 5096), tuple(65602, 83431), tuple(97198, 10971), tuple(4873, 51104), + tuple(49700, 89396), tuple(18900, 20447), tuple(76400, 68088), tuple(28055, 59547), tuple(94737, 96052), tuple(57933, 96132), tuple(26945, 6293), tuple(18559, 1317), tuple(66327, 78332), tuple(47194, 67979), tuple(78039, 58735), tuple(26666, 96144), tuple(91574, 52530), tuple(3216, 43850), tuple(48367, 78987), tuple(78296, 89800), tuple(25015, 1497), tuple(70292, 37629), tuple(39657, 59240), tuple(22576, 93232), tuple(70102, 98407), tuple(35051, 5762), tuple(13700, 82540), tuple(36857, 7528), tuple(84536, 86107), tuple(1258, 90702), tuple(9152, 1127), tuple(3136, 57298), tuple(73203, 93120), tuple(61897, 32903), tuple(20284, 49358), tuple(49444, 65481), tuple(91260, 84792), tuple(5360, 37164), tuple(79212, 26499), tuple(59456, 37025), tuple(67953, 53566), tuple(50253, 71742), tuple(68181, 90923), tuple(88522, 71071), tuple(89615, 46115), tuple(31661, 17673), tuple(37699, 90994), tuple(41974, 9481), tuple(51974, 46364), tuple(47470, 75958), tuple(38427, 78267), tuple(90226, 16121), tuple(33257, 3088), tuple(73044, 79701), tuple(14149, 36868), tuple(6421, 63653), tuple(35772, 56493), tuple(46665, 83651), tuple(82299, 56268), tuple(77397, 71795), tuple(15180, 87135), tuple(73936, 38858), tuple(27060, 14829), tuple(85847, 76756), tuple(63068, 61864), tuple(92040, 43753), tuple(53882, 60715), tuple(12648, 18276), tuple(17873, 94081), tuple(55982, 24983), tuple(52686, 32111), tuple(22555, 13144), tuple(37190, 15039), tuple(47304, 86179), tuple(56214, 83657), tuple(53838, 78111), tuple(80530, 1686), tuple(2976, 26711), tuple(55713, 3487), tuple(21157, 5923), tuple(74613, 76555), tuple(61736, 7322), tuple(99017, 13779), tuple(64133, 61706), tuple(8276, 97269), tuple(99641, 87447), tuple(26292, 62924), tuple(96267, 37877), tuple(98635, 88685), tuple(65598, 68210), tuple(34885, 1063), tuple(42880, 15694), tuple(4058, 72666), tuple(1319, 91582), tuple(41749, 822), tuple(82490, 42783), tuple(17489, 17617), tuple(81109, 16778), tuple(86262, 53756), tuple(15547, 21144), tuple(89799, 70465), tuple(99358, 87334), tuple(65501, 81932), tuple(30351, 64230), tuple(55974, 46985), tuple(24343, 93628), tuple(4624, 56038), tuple(15183, 38765), tuple(21562, 5240), tuple(36215, 51533), tuple(49649, 74392), tuple(7607, 91204), tuple(86233, 85341), tuple(35494, 44178), tuple(78808, 11896), tuple(45446, 12897), tuple(4810, 20096), tuple(3643, 10550), tuple(12022, 14391), tuple(99014, 87891), tuple(67214, 29437), tuple(7015, 54810), tuple(84991, 75251), tuple(45526, 82687), tuple(43608, 89083), tuple(96191, 12911), tuple(36902, 50415), tuple(90548, 66839), tuple(54007, 5480), tuple(57191, 39709), tuple(73364, 73556), tuple(12671, 64072), tuple(5047, 12887), tuple(22326, 88360), tuple(59259, 63167), tuple(39237, 9311), tuple(47043, 11512), tuple(32399, 22634), tuple(89485, 95279), tuple(30489, 43327), tuple(70966, 18184), tuple(28514, 12686), tuple(1717, 89938), tuple(14871, 76911), tuple(47862, 97093), tuple(97572, 77612), tuple(88600, 36501), tuple(9240, 96264), tuple(96629, 98292), tuple(4838, 72694), tuple(52835, 73039), tuple(63836, 26228), tuple(26035, 74526), tuple(23617, 6104), tuple(6243, 54603), tuple(20038, 81195), tuple(56789, 96284), + tuple(97009, 18989), tuple(36765, 94831), tuple(42002, 40820), tuple(31838, 16186), tuple(91127, 70783), tuple(1684, 38076), tuple(40928, 41294), tuple(97107, 76517), tuple(1797, 24093), tuple(99175, 29445), tuple(5788, 64502), tuple(66972, 23772), tuple(97394, 95256), tuple(26705, 92412), tuple(10676, 6686), tuple(28464, 74051), tuple(17598, 51675), tuple(76449, 50050), tuple(98812, 59818), tuple(92058, 6625), tuple(49804, 99637), tuple(28545, 32790), tuple(72167, 93636), tuple(29012, 95623), tuple(58249, 54541), tuple(98926, 71489), tuple(75062, 9546), tuple(47555, 5802), tuple(61606, 30979), tuple(10467, 46108), tuple(30491, 52750), tuple(52934, 38533), tuple(54616, 37276), tuple(55118, 2330), tuple(60402, 14806), tuple(25730, 88759), tuple(5209, 30946), tuple(92017, 41987), tuple(59747, 62415), tuple(6306, 53297), tuple(35770, 31254), tuple(13106, 99865), tuple(63519, 41637), tuple(7416, 68154), tuple(70874, 95983), tuple(20074, 2173), tuple(33740, 86880), tuple(45020, 65869), tuple(7302, 53494), tuple(98814, 2118), tuple(88287, 80646), tuple(18771, 30449), tuple(44557, 37984), tuple(45415, 36032), tuple(36584, 58485), tuple(57843, 52354), tuple(85647, 12150), tuple(33990, 89380), tuple(98597, 41936), tuple(19427, 53990), tuple(1457, 69269), tuple(68438, 14471), tuple(67175, 16881), tuple(82982, 78546), tuple(47661, 36294), tuple(63229, 48108), tuple(34390, 76095), tuple(32101, 57268), tuple(25322, 3312), tuple(17037, 2900), tuple(14342, 70149), tuple(10518, 1377), tuple(13553, 89073), tuple(97084, 80365), tuple(48340, 87192), tuple(84969, 21195), tuple(1031, 72944), tuple(78322, 68583), tuple(67238, 48374), tuple(77366, 55850), tuple(4383, 46759), tuple(51088, 76488), tuple(92049, 55847), tuple(32750, 16422), tuple(51788, 53619), tuple(56976, 88951), tuple(73323, 78435), tuple(3489, 15945), tuple(84231, 22302), tuple(25695, 881), tuple(19391, 11660), tuple(92578, 78349), tuple(52677, 17339), tuple(99132, 35975), tuple(25089, 70476), tuple(34144, 66544), tuple(59589, 59839), tuple(47333, 87623), tuple(4200, 6542), tuple(91781, 77813), tuple(77419, 17342), tuple(388, 90753), tuple(43401, 7351), tuple(81829, 74989), tuple(22381, 95695), tuple(90302, 61687), tuple(13534, 54534), tuple(43527, 47703), tuple(47856, 1186), tuple(10112, 16747), tuple(9508, 26179), tuple(96536, 57565), tuple(91052, 48922), tuple(38575, 45523), tuple(11602, 85317), tuple(22595, 21610), tuple(97849, 15638), tuple(95060, 20111), tuple(96011, 27148), tuple(37596, 10426), tuple(68667, 49057), tuple(68657, 90882), tuple(52704, 33574), tuple(54727, 59704), tuple(15853, 48283), tuple(47021, 60021), tuple(96208, 11440), tuple(6068, 49421), tuple(50363, 17684), tuple(53218, 19), tuple(82568, 3816), tuple(51, 7612), tuple(7073, 59063), tuple(92318, 38587), tuple(72388, 64952), tuple(33318, 5594), tuple(72806, 18573), tuple(1175, 88747), tuple(67044, 86039), tuple(17376, 41265), tuple(26356, 89524), tuple(55678, 15627), tuple(61156, 15723), tuple(43239, 59010), tuple(29054, 15261), tuple(57669, 21395), tuple(68469, 14849), tuple(92654, 69664), tuple(23975, 20021), tuple(73688, 12134), tuple(58053, 23849), tuple(56234, 18559), tuple(25051, 68957), tuple(15181, 91615), tuple(87633, 31040), tuple(17494, 78515), tuple(71971, 60923), tuple(44170, 21724), tuple(7088, 72107), tuple(12924, 47933), tuple(98139, 6819), tuple(57842, 2906), tuple(90278, 3534), tuple(61695, 82885), tuple(58831, 15129), tuple(32033, 34634), tuple(63477, 31357), tuple(29077, 28166), tuple(86531, 89574), tuple(46943, 79113), tuple(15667, 63523), tuple(65818, 93225), tuple(83392, 50497), tuple(7157, 88909), tuple(95101, 17111), tuple(8981, 35791), tuple(28328, 82722), tuple(70215, 66862), tuple(23442, 39128), tuple(21218, 27773), tuple(76215, 39265), tuple(56858, 62397), tuple(3610, 8766), tuple(7423, 48886), tuple(12235, 88792), tuple(44839, 55196), tuple(4896, 10080), tuple(87090, 73997), tuple(56745, 71875), tuple(58478, 57472), tuple(79423, 8771), tuple(76202, 95733), tuple(81635, 48857), tuple(82519, 5321), tuple(48756, 37198), tuple(20101, 61177), tuple(79047, 81682), tuple(23287, 88578), tuple(50984, 80946), tuple(855, 49074), tuple(11452, 56655), tuple(6289, 8916), tuple(33570, 636), tuple(28703, 80592), tuple(11820, 92299), tuple(75590, 80188), tuple(91365, 2787), tuple(22963, 43710), tuple(3996, 48007), tuple(59047, 96418), tuple(96710, 52447), tuple(65677, 99927), tuple(60727, 15115), tuple(8161, 65729), tuple(75253, 45731), tuple(88130, 79264), tuple(52087, 32657), tuple(89678, 22834), tuple(49244, 36835), tuple(74032, 5096), tuple(94142, 39297), tuple(51061, 21311), tuple(59391, 43458), tuple(90918, 95081), tuple(6058, 37018), tuple(29917, 54214), tuple(65986, 5543), tuple(99777, 69683), tuple(9447, 11273), tuple(54873, 47138), tuple(1306, 68306), tuple(15316, 55995), tuple(69280, 73432), tuple(63054, 28502), tuple(67161, 11333), tuple(40800, 26415), tuple(72350, 50225), tuple(7232, 67500), tuple(60631, 40338), tuple(96765, 51671), tuple(29375, 11235), tuple(52707, 93742), tuple(1317, 55926), tuple(51844, 29351), tuple(35754, 16733), tuple(23014, 56950), tuple(33119, 47531), tuple(27806, 39940), tuple(20119, 73119), tuple(18458, 45982), tuple(16605, 28759), tuple(43488, 86201), tuple(43560, 82883), tuple(85085, 1977), tuple(7129, 64077), tuple(36070, 80679), tuple(78638, 97212), tuple(71251, 5268), tuple(33610, 63341), tuple(16722, 15882), tuple(53876, 11734), tuple(35855, 14481), tuple(55072, 7889), tuple(37213, 73390), tuple(28899, 55948), tuple(51996, 77777), tuple(26621, 51914), tuple(44492, 36420), tuple(36437, 24452), tuple(158, 77935), tuple(3730, 7692), tuple(81372, 29050), tuple(29491, 3912), tuple(57098, 73393), tuple(55630, 53165), tuple(79003, 19421), tuple(47306, 40128), tuple(96332, 49995), tuple(54107, 83940), tuple(11203, 76678), tuple(53854, 284), tuple(96087, 22398), tuple(25481, 69301), tuple(2770, 77586), tuple(53004, 44915), tuple(56264, 41165), tuple(12335, 22090), tuple(47188, 40678), tuple(41823, 71805), tuple(81810, 47825), tuple(98892, 50696), tuple(74323, 93133), tuple(82867, 40800), tuple(28884, 29276), tuple(55697, 20888), tuple(96901, 37428), tuple(95509, 78780), tuple(6443, 65188), tuple(17669, 43924), tuple(29933, 97244), tuple(1024, 71265), tuple(47229, 99610), tuple(72546, 40811), tuple(43407, 41566), tuple(44692, 53743), tuple(76823, 95950), tuple(2509, 57091), tuple(85077, 96439), tuple(87650, 87716), tuple(3822, 84513), tuple(90864, 75439), tuple(22043, 21770), tuple(98371, 75482), tuple(63823, 48100), tuple(29999, 40875), tuple(97696, 33865), tuple(50880, 16402), tuple(21412, 70936), tuple(7150, 85970), tuple(73104, 57073), tuple(40099, 89138), tuple(6430, 36791), tuple(47677, 23485), tuple(21073, 86912), tuple(65018, 6092), tuple(89932, 58178), tuple(1264, 51681), tuple(42044, 40135), tuple(21774, 12190), tuple(13844, 87188), tuple(25807, 89548), tuple(74682, 31603), tuple(18482, 41232), tuple(906, 21841), tuple(10897, 39238), tuple(62134, 6083), tuple(80871, 66850), tuple(49659, 28587), tuple(61260, 22769), tuple(53795, 66637), tuple(89211, 32453), tuple(4271, 69472), tuple(1082, 32636), tuple(62012, 47870), tuple(7376, 77166), tuple(13150, 73275), tuple(66410, 85959), tuple(19018, 57311), tuple(30561, 58838), tuple(19981, 32087), tuple(91580, 42990), tuple(77139, 23774), tuple(10055, 99890), tuple(92160, 54537), tuple(75088, 70397), tuple(2361, 61066), tuple(81368, 40411), tuple(84946, 42564), tuple(41591, 42929), tuple(50399, 26116), tuple(51504, 63772), tuple(99828, 69531), tuple(19977, 17806), tuple(71259, 76567), tuple(78606, 25105), tuple(8859, 46469), tuple(19542, 73988), tuple(49804, 17349), tuple(65360, 96632), tuple(57740, 30812), tuple(9258, 26185), tuple(90573, 4815), tuple(39397, 10229), tuple(35300, 81687), tuple(5681, 22828), tuple(6274, 38340), tuple(44281, 67912), tuple(38385, 26507), tuple(95324, 84765), tuple(39288, 79779), tuple(4513, 28158), tuple(46060, 40293), tuple(70348, 87460), tuple(67754, 19569), tuple(70481, 94407), tuple(67636, 69316), tuple(14167, 81744), tuple(18928, 29706), tuple(32034, 45677), tuple(19801, 5902), tuple(42401, 62712), tuple(35220, 22823), tuple(33690, 22046), tuple(91281, 55953), tuple(4197, 96279), tuple(32901, 27074), tuple(35861, 5478), tuple(99166, 36251), tuple(70898, 80994), tuple(87491, 52808), tuple(59681, 30266), tuple(2944, 18646), tuple(77874, 7536), tuple(24534, 5416), tuple(90962, 47145), tuple(95367, 34461), tuple(10075, 74120), tuple(74276, 1837), tuple(38399, 63918), tuple(10526, 42662), tuple(33001, 37773), tuple(13642, 25741), tuple(5373, 82728), tuple(9830, 54625), tuple(13, 18937), tuple(90113, 52300), tuple(20973, 89640), tuple(44930, 1598), tuple(8100, 47745), tuple(80659, 78877), tuple(74154, 33417), tuple(18691, 37573), tuple(12477, 76628), tuple(73018, 89583), tuple(59029, 24879), tuple(85237, 31017), tuple(27701, 11025), tuple(24010, 76942), tuple(15627, 25276), tuple(89050, 16118), tuple(19776, 19318), tuple(24620, 1487), tuple(50157, 95158), tuple(53030, 72020), tuple(85571, 10817), tuple(29196, 92799), tuple(63501, 22445), tuple(26241, 54318), tuple(33769, 80112), tuple(25312, 50574), tuple(70583, 56662), tuple(74366, 82575), tuple(48461, 80545), tuple(18834, 39444), tuple(36597, 42715), tuple(86547, 38453), tuple(41067, 60718), tuple(33350, 25404), tuple(5532, 41438), tuple(45918, 84038), tuple(39040, 63724), tuple(37629, 66002), tuple(58037, 36196), tuple(21400, 17330), tuple(46491, 22602), tuple(88057, 89249), tuple(34188, 35948), tuple(8555, 42479), tuple(32961, 76606), tuple(22395, 93711), tuple(8058, 19591), tuple(72063, 64136), tuple(83360, 12607), tuple(20671, 78285), tuple(51887, 65373), tuple(71966, 39341), tuple(55953, 99780), tuple(56205, 98138), tuple(45986, 44708), tuple(62541, 28259), tuple(49450, 12641), tuple(5192, 36601), tuple(55295, 44352), tuple(83762, 4343), tuple(96203, 8870), tuple(21786, 73828), tuple(88830, 43827), tuple(96669, 84761), tuple(53061, 50061), tuple(52150, 47463), tuple(32090, 17570), + tuple(71495, 45027), tuple(30215, 23717), tuple(37599, 19789), tuple(85208, 48465), tuple(83599, 78596), tuple(82141, 37105), tuple(74943, 37580), tuple(10322, 11520), tuple(550, 55062), tuple(80506, 57713), tuple(55489, 80453), tuple(64174, 49274), tuple(75521, 51005), tuple(26033, 58801), tuple(78661, 50218), tuple(31043, 17090), tuple(70612, 88736), tuple(42991, 49396), tuple(86331, 2300), tuple(66156, 6331), tuple(34534, 78649), tuple(9828, 40937), tuple(35852, 46533), tuple(68435, 12070), tuple(26443, 75772), tuple(50802, 16400), tuple(69413, 89875), tuple(2372, 97252), tuple(88334, 76754), tuple(29504, 25950), tuple(10792, 12935), tuple(3655, 90667), tuple(35951, 16244), tuple(73312, 82435), tuple(60914, 58748), tuple(89407, 86955), tuple(47210, 84195), tuple(77084, 4213), tuple(15419, 5719), tuple(12483, 39092), tuple(61890, 83360), tuple(94785, 37525), tuple(69219, 83790), tuple(79946, 42672), tuple(36898, 9693), tuple(10103, 82234), tuple(71679, 18297), tuple(88171, 43635), tuple(94828, 71283), tuple(76485, 56217), tuple(70048, 92642), tuple(12567, 8082), tuple(10011, 76160), tuple(31060, 30787), tuple(199, 65728), tuple(371, 74295), tuple(25505, 76411), tuple(70522, 8776), tuple(58390, 48835), tuple(88649, 10695), tuple(21754, 5143), tuple(62512, 77235), tuple(837, 57129), tuple(86979, 33448), tuple(21219, 78593), tuple(10048, 22504), tuple(82658, 80394), tuple(79451, 81707), tuple(5940, 72284), tuple(1555, 70284), tuple(65988, 40439), tuple(48165, 92837), tuple(33680, 39653), tuple(96852, 38612), tuple(72548, 82912), tuple(78383, 68910), tuple(69985, 12164), tuple(24334, 14856), tuple(27180, 67558), tuple(62131, 29120), tuple(28744, 40472), tuple(79896, 25579), tuple(7172, 42815), tuple(81070, 85827), tuple(76227, 51604), tuple(70056, 61128), tuple(58609, 12641), tuple(30207, 33772), tuple(7940, 82930), tuple(45176, 28620), tuple(43176, 9513), tuple(55515, 5743), tuple(92762, 34063), tuple(26540, 95690), tuple(69518, 13909), tuple(24403, 65731), tuple(41317, 12732), tuple(78020, 50738), tuple(64622, 2001), tuple(43604, 83548), tuple(46739, 79104), tuple(57132, 2737), tuple(16823, 37703), tuple(59239, 68217), tuple(49630, 75156), tuple(19535, 63429), tuple(19685, 63032), tuple(93214, 97701), tuple(21809, 44089), tuple(42700, 64026), tuple(37310, 12041), tuple(84416, 39080), tuple(70589, 59876), tuple(14692, 82526), tuple(36230, 38375), tuple(7345, 48208), tuple(65006, 85251), tuple(31754, 26359), tuple(65198, 7876), tuple(38917, 16682), tuple(39527, 24043), tuple(28543, 48728), tuple(38065, 98259), tuple(57509, 71565), tuple(7706, 85866), tuple(13059, 22966), tuple(91722, 83066), tuple(45269, 68810), tuple(82194, 85898), tuple(78369, 11390), tuple(79637, 70777), tuple(87544, 74018), tuple(73661, 4252), tuple(98305, 21715), tuple(19375, 35375), tuple(28324, 48444), tuple(97548, 89589), tuple(73031, 60766), tuple(34818, 1986), tuple(6206, 26488), tuple(67681, 6380), tuple(98946, 84665), tuple(98568, 37447), tuple(48649, 89141), tuple(72561, 2077), tuple(47055, 63199), tuple(3956, 93341), tuple(69392, 51121), tuple(71277, 40181), tuple(8509, 18405), tuple(77921, 54923), tuple(92137, 60652), tuple(30271, 32980), + tuple(60001, 93265), tuple(69240, 45514), tuple(57985, 21681), tuple(35096, 6101), tuple(49506, 76284), tuple(57253, 21325), tuple(98280, 15826), tuple(1605, 80735), tuple(74930, 30151), tuple(58035, 93534), tuple(17384, 31491), tuple(10971, 7060), tuple(73339, 68186), tuple(88781, 52103), tuple(11265, 46720), tuple(5115, 30293), tuple(75078, 87304), tuple(43439, 10072), tuple(27578, 33361), tuple(90981, 10158), tuple(24465, 57967), tuple(49938, 61510), tuple(55637, 44188), tuple(93963, 32210), tuple(68414, 40035), tuple(77261, 88709), tuple(55900, 34360), tuple(39675, 19672), tuple(66218, 19215), tuple(74660, 74886), tuple(82862, 19255), tuple(78221, 82950), tuple(71132, 13770), tuple(3866, 56030), tuple(78929, 78110), tuple(48142, 5965), tuple(80128, 31846), tuple(72670, 2531), tuple(14391, 67079), tuple(60542, 10720), tuple(91632, 40402), tuple(607, 14720), tuple(49500, 13967), tuple(70778, 83672), tuple(46041, 37708), tuple(83720, 574), tuple(57212, 80758), tuple(28854, 46858), tuple(39588, 19052), tuple(50803, 71521), tuple(66830, 71799), tuple(21002, 61070), tuple(96634, 39051), tuple(4459, 26782), tuple(63650, 82860), tuple(24099, 69429), tuple(80492, 18147), tuple(41087, 995), tuple(41768, 79625), tuple(48190, 75710), tuple(43300, 78132), tuple(53778, 79772), tuple(30657, 89149), tuple(75840, 5676), tuple(75810, 52995), tuple(36563, 23231), tuple(25721, 55136), tuple(15, 23168), tuple(63731, 64535), tuple(67136, 4648), tuple(25464, 28946), tuple(95215, 98695), tuple(64093, 28899), tuple(62809, 40760), tuple(44188, 52915), tuple(82358, 98065), tuple(24244, 56401), tuple(61636, 63848), tuple(95428, 93970), tuple(93539, 88332), tuple(57401, 68773), tuple(53502, 33067), tuple(3147, 65487), tuple(75811, 11287), tuple(58826, 7349), tuple(57494, 66861), tuple(99762, 33031), tuple(68299, 20951), tuple(26524, 96915), tuple(14698, 22392), tuple(55683, 85344), tuple(25084, 10755), tuple(52343, 73138), tuple(99839, 61148), tuple(33383, 66190), tuple(18810, 10835), tuple(918, 55695), tuple(2664, 46566), tuple(93105, 21138), tuple(27088, 16730), tuple(70156, 4974), tuple(10294, 62096), tuple(30808, 18639), tuple(25091, 43231), tuple(17920, 90076), tuple(40104, 54257), tuple(98729, 93113), tuple(92419, 16006), tuple(14446, 8769), tuple(24875, 34761), tuple(99525, 34543), tuple(67461, 47601), tuple(91998, 5899), tuple(19623, 58521), tuple(97278, 63650), tuple(8396, 20069), tuple(29854, 22735), tuple(33695, 25257), tuple(70338, 3989), tuple(14296, 96530), tuple(13790, 1350), tuple(33144, 55649), tuple(29072, 26337), tuple(68611, 7960), tuple(81765, 15614), tuple(16633, 80649), tuple(89942, 31234), tuple(50827, 73426), tuple(2282, 12998), tuple(8566, 65109), tuple(65979, 23638), tuple(24802, 56043), tuple(15638, 54100), tuple(51431, 80669), tuple(30744, 9349), tuple(80148, 87322), tuple(49673, 22775), tuple(2096, 72107), tuple(29876, 11845), tuple(99687, 4215), tuple(68797, 41891), tuple(11363, 79333), tuple(22351, 68211), tuple(41273, 34990), tuple(11414, 58625), tuple(83047, 28825), tuple(44579, 31219), tuple(8753, 35994), tuple(8321, 20399), tuple(97524, 48382), tuple(81485, 69822), tuple(38382, 42853), tuple(97045, 81294), tuple(95109, 9825), tuple(24648, 92398), tuple(23245, 28557), tuple(9114, 30750), tuple(66151, 5307), tuple(28704, 42997), tuple(76185, 18506), tuple(39182, 28385), tuple(12660, 487), tuple(81939, 70723), tuple(78752, 4369), tuple(49729, 16078), tuple(27760, 78394), tuple(27935, 65985), tuple(97170, 17974), tuple(45484, 51849), tuple(37792, 42775), tuple(50788, 50243), tuple(29730, 5771), tuple(8337, 32970), tuple(87282, 34536), tuple(82654, 40374), tuple(25936, 99591), tuple(87105, 44686), tuple(61326, 23201), tuple(48961, 39310), tuple(72404, 34074), tuple(47084, 53440), tuple(44566, 21551), tuple(27348, 31756), tuple(14445, 57694), tuple(3090, 78935), tuple(37165, 19519), tuple(42821, 24648), tuple(4987, 91817), tuple(15902, 33578), tuple(63028, 39291), tuple(9567, 41818), tuple(68851, 3311), tuple(1641, 59714), tuple(51932, 83190), tuple(40656, 19271), tuple(44882, 35988), tuple(94241, 78634), tuple(15970, 79214), tuple(11262, 56304), tuple(46638, 79764), tuple(9206, 54131), tuple(77132, 24211), tuple(38417, 34891), tuple(55196, 29011), tuple(64734, 42845), tuple(33857, 44248), tuple(40460, 66582), tuple(34542, 273), tuple(84169, 65245), tuple(83434, 25030), tuple(10937, 1189), tuple(35213, 89760), tuple(48231, 5149), tuple(49920, 97597), tuple(56463, 13926), tuple(35160, 4587), tuple(91526, 85881), tuple(38624, 54542), tuple(17138, 93601), tuple(16139, 72928), tuple(93357, 75097), tuple(84733, 99796), tuple(39474, 98875), tuple(97908, 58734), tuple(97237, 91217), tuple(77132, 32920), tuple(85467, 32730), tuple(83289, 18742), tuple(2980, 4330), tuple(44920, 11778), tuple(30191, 82779), tuple(34431, 45207), tuple(75529, 10325), tuple(4657, 36429), tuple(97464, 18604), tuple(29451, 14997), tuple(40066, 22598), tuple(49471, 66259), tuple(65164, 98515), tuple(64098, 47692), tuple(87542, 84786), tuple(41170, 49570), tuple(11476, 14536), tuple(82271, 79916), tuple(45889, 42059), tuple(84965, 90533), tuple(88733, 20381), tuple(86349, 66190), tuple(83280, 32409), tuple(38436, 35910), tuple(94362, 2535), tuple(13565, 12567), tuple(72551, 58564), tuple(886, 87999), tuple(73958, 94309), tuple(34030, 60715), tuple(25432, 92697), tuple(85922, 24244), tuple(46779, 52990), tuple(33807, 44621), tuple(39513, 51405), tuple(16668, 32353), tuple(60629, 14813), tuple(73095, 12227), tuple(17801, 38366), tuple(65927, 52833), tuple(33630, 50134), tuple(19975, 71026), tuple(93145, 90036), tuple(73555, 6383), tuple(71789, 81791), tuple(67429, 79036), tuple(20944, 39911), tuple(75838, 56480), tuple(29835, 80194), tuple(19570, 28901), tuple(16023, 82165), tuple(74259, 15283), tuple(11749, 92274), tuple(73537, 52362), tuple(54537, 37595), tuple(79004, 72436), tuple(49229, 21498), tuple(24364, 97373), tuple(81149, 61392), tuple(22421, 6442), tuple(62138, 86081), tuple(16098, 23700), tuple(66604, 86467), tuple(66505, 26263), tuple(57215, 12659), tuple(61267, 77421), tuple(58024, 98298), tuple(44273, 89699), tuple(62339, 73107), tuple(32540, 17768), tuple(31574, 77296), tuple(63336, 23439), tuple(26723, 45141), tuple(61380, 58474), tuple(6188, 2084), tuple(88225, 6631), tuple(10970, 70428), tuple(91223, 64312), tuple(89643, 76635), tuple(42796, 77154), tuple(34827, 21131), tuple(83014, 2253), tuple(34547, 12384), tuple(53922, 57591), tuple(12066, 44400), tuple(89686, 21284), tuple(81875, 3306), tuple(45972, 11207), tuple(96807, 28447), tuple(87662, 42334), tuple(68578, 37404), tuple(21195, 35583), tuple(97730, 41852), tuple(76425, 22959), tuple(63724, 64143), tuple(79182, 50739), tuple(81472, 79682), tuple(26980, 62332), tuple(60691, 50596), tuple(38526, 10488), tuple(74569, 46431), tuple(62677, 60189), tuple(35133, 21147), tuple(3271, 93368), tuple(14651, 76080), tuple(91349, 87952), tuple(7873, 51144), tuple(72431, 54715), tuple(15600, 69868), tuple(46998, 23805), tuple(7519, 75777), tuple(71758, 71673), tuple(23282, 37297), tuple(35646, 89327), tuple(44890, 58293), tuple(34223, 99155), tuple(87015, 18477), tuple(20511, 30210), tuple(82120, 13850), tuple(6382, 41946), tuple(97741, 86276), tuple(15521, 44501), tuple(87240, 57472), tuple(65334, 51695), tuple(34599, 97721), tuple(45366, 9007), tuple(91971, 7384), tuple(74698, 40735), tuple(73706, 9025), tuple(42569, 18928), tuple(62946, 62362), tuple(89350, 83255), tuple(26044, 85080), tuple(27725, 3814), tuple(45787, 32352), tuple(16115, 51701), tuple(3339, 72851), tuple(60161, 34406), tuple(24699, 43473), tuple(28681, 573), tuple(95106, 16784), tuple(74232, 5831), tuple(55361, 1366), tuple(7020, 37807), tuple(52490, 8558), tuple(91203, 64944), tuple(90783, 64700), tuple(76499, 12592), tuple(97070, 9395), tuple(46602, 12688), tuple(79052, 31675), tuple(29316, 93503), tuple(14095, 3100), tuple(15066, 86579), tuple(24651, 10981), tuple(90683, 70162), tuple(60604, 89175), tuple(55172, 34997), tuple(61098, 17843), tuple(2376, 21399), tuple(38186, 60680), tuple(58637, 11541), tuple(11101, 69351), tuple(70200, 67918), tuple(49245, 85252), tuple(4201, 24436), tuple(56636, 87099), tuple(21406, 33757), tuple(29044, 43846), tuple(93900, 68223), tuple(34429, 92683), tuple(76720, 79334), tuple(4035, 30364), tuple(20145, 44853), tuple(46689, 21352), tuple(49446, 77224), tuple(71241, 85720), tuple(27177, 88332), tuple(60151, 49376), tuple(67102, 74396), tuple(242, 26346), tuple(22004, 95064), tuple(2709, 71452), tuple(71673, 86838), tuple(36918, 17777), tuple(37414, 88149), tuple(2356, 70290), tuple(84416, 35509), tuple(32285, 54585), tuple(9937, 23465), tuple(3385, 25949), tuple(97379, 87409), tuple(72714, 43570), tuple(54831, 64883), tuple(80885, 81082), tuple(89673, 5765), tuple(84585, 51627), tuple(64497, 72931), tuple(71948, 60922), tuple(70011, 37446), tuple(81022, 43696), tuple(11413, 58709), tuple(89710, 85350), tuple(96004, 36589), tuple(99270, 82834), tuple(52367, 12117), tuple(62108, 56693), tuple(69090, 34612), tuple(56109, 22008), tuple(36036, 34493), tuple(88561, 4651), tuple(44403, 60712), tuple(91912, 19116), tuple(40545, 94625), tuple(47973, 46963), tuple(30704, 99285), tuple(9596, 21976), tuple(84723, 81323), tuple(98123, 90434), tuple(35842, 29225), tuple(91271, 14003), tuple(42320, 16108), tuple(14171, 88861), tuple(15139, 84030), tuple(31008, 58743), tuple(86149, 98215), tuple(59768, 15217), tuple(85628, 82450), tuple(14256, 2254), tuple(44961, 44326), tuple(86313, 69953), tuple(99151, 37777), tuple(46152, 77035), tuple(36868, 62695), tuple(37233, 49305), tuple(20706, 56446), tuple(75773, 90240), tuple(88130, 91556), tuple(89753, 38172), tuple(31191, 98583), tuple(31412, 81334), tuple(57662, 15890), tuple(9195, 3322), tuple(94618, 22144), tuple(24709, 24446), tuple(54382, 68062), tuple(17085, 30960), tuple(53538, 12827), tuple(12512, 56172), tuple(26611, 90242), tuple(92812, 98619), tuple(82930, 90399), tuple(2299, 45362), tuple(48505, 88997), + tuple(58709, 77683), tuple(85901, 33672), tuple(45070, 24491), tuple(79005, 44787), tuple(7154, 14290), tuple(56684, 35166), tuple(76459, 60609), tuple(6006, 47402), tuple(54755, 19015), tuple(5139, 33177), tuple(13725, 50051), tuple(95929, 58683), tuple(91114, 68401), tuple(88846, 23283), tuple(37153, 36426), tuple(36564, 32035), tuple(49852, 49501), tuple(2052, 59285), tuple(69847, 54966), tuple(82614, 10395), tuple(72068, 35582), tuple(50427, 19892), tuple(75612, 3545), tuple(75480, 26985), tuple(24227, 50112), tuple(22718, 52206), tuple(35801, 41679), tuple(17753, 44416), tuple(4688, 82170), tuple(36935, 6606), tuple(71549, 86720), tuple(53592, 68769), tuple(92671, 84617), tuple(97726, 13655), tuple(65006, 17474), tuple(25287, 80826), tuple(22202, 25703), tuple(98743, 71876), tuple(72914, 31392), tuple(54184, 1294), tuple(9353, 10518), tuple(93822, 74538), tuple(85863, 56357), tuple(56088, 14448), tuple(12427, 27727), tuple(1846, 350), tuple(96301, 21623), tuple(55225, 23813), tuple(76947, 60946), tuple(65400, 17489), tuple(80586, 79099), tuple(56913, 46914), tuple(49218, 53295), tuple(14085, 52313), tuple(71158, 14144), tuple(3641, 69327), tuple(43705, 93045), tuple(67880, 95849), tuple(88054, 66156), tuple(17425, 69320), tuple(16391, 271), tuple(31768, 8817), tuple(63156, 21471), tuple(97831, 43504), tuple(54300, 54402), tuple(8740, 27894), tuple(93805, 30183), tuple(76233, 26322), tuple(60307, 8348), tuple(63019, 32334), tuple(7086, 44838), tuple(93127, 94482), tuple(20146, 84889), tuple(33674, 2513), tuple(66860, 65753), tuple(69174, 35906), tuple(93800, 41975), tuple(31206, 93599), tuple(75620, 60674), tuple(77082, 60773), tuple(75564, 20627), tuple(53060, 67879), tuple(52568, 22722), tuple(4102, 42037), tuple(66549, 71191), tuple(20817, 80946), tuple(13469, 96144), tuple(29852, 713), tuple(72644, 98510), tuple(12567, 54057), tuple(28746, 72197), tuple(80235, 51566), tuple(11953, 73225), tuple(42732, 91659), tuple(19673, 29661), tuple(94438, 41029), tuple(21884, 91078), tuple(29280, 68018), tuple(973, 75825), tuple(83476, 79334), tuple(99077, 625), tuple(63309, 91304), tuple(11626, 33709), tuple(33735, 6897), tuple(12585, 17114), tuple(45256, 57549), tuple(65150, 2524), tuple(10399, 34571), tuple(32783, 6045), tuple(11900, 12875), tuple(4393, 3129), tuple(61420, 63521), tuple(11799, 9092), tuple(45887, 36931), tuple(84256, 71195), tuple(51949, 32406), tuple(34640, 11424), tuple(84866, 46109), tuple(23449, 51873), tuple(22371, 86773), tuple(32155, 25902), tuple(75058, 66016), tuple(21217, 19002), tuple(44067, 59363), tuple(55901, 87102), tuple(71213, 82390), tuple(88408, 22154), tuple(18231, 86852), tuple(96803, 72776), tuple(58608, 53500), tuple(40747, 8542), tuple(60870, 41475), tuple(39578, 66560), tuple(49522, 25492), tuple(3485, 13917), tuple(60177, 43310), tuple(70317, 69166), tuple(71910, 92946), tuple(14427, 320), tuple(5224, 79108), tuple(20986, 81899), tuple(34637, 53572), tuple(14919, 27426), tuple(8052, 10082), tuple(27936, 24128), tuple(73732, 97758), tuple(31869, 5719), tuple(22135, 86985), tuple(85977, 79381), tuple(41587, 34012), tuple(75912, 66428), tuple(62117, 37249), tuple(70197, 91261), + tuple(99703, 96452), tuple(33036, 30249), tuple(33709, 99448), tuple(30343, 2962), tuple(54245, 80785), tuple(13866, 99804), tuple(49392, 62886), tuple(8530, 38228), tuple(86249, 60394), tuple(96787, 88788), tuple(42724, 88066), tuple(97051, 85589), tuple(41414, 88972), tuple(4384, 2025), tuple(46524, 87620), tuple(5823, 36079), tuple(78720, 13519), tuple(59092, 88699), tuple(24120, 6388), tuple(51664, 71039), tuple(28756, 43890), tuple(13729, 27176), tuple(86717, 82448), tuple(65598, 34805), tuple(74975, 52791), tuple(65429, 97173), tuple(92472, 53334), tuple(18778, 40576), tuple(72776, 48956), tuple(61833, 85936), tuple(81344, 48055), tuple(89467, 91099), tuple(82333, 15367), tuple(6019, 98391), tuple(52943, 15338), tuple(29662, 21975), tuple(71935, 47606), tuple(54633, 72216), tuple(51648, 52203), tuple(84649, 31791), tuple(26281, 82065), tuple(83163, 43394), tuple(79859, 55897), tuple(84706, 38368), tuple(97175, 88009), tuple(92800, 82164), tuple(79819, 13645), tuple(42754, 6273), tuple(97025, 79579), tuple(35694, 44160), tuple(96053, 24801), tuple(60315, 14411), tuple(25961, 82303), tuple(1791, 53355), tuple(15508, 43236), tuple(35667, 84655), tuple(73764, 82190), tuple(14465, 72390), tuple(92464, 30555), tuple(14121, 31360), tuple(27630, 78672), tuple(35483, 47439), tuple(79467, 73233), tuple(33010, 49718), tuple(43095, 2002), tuple(3755, 4070), tuple(25460, 21281), tuple(52718, 27575), tuple(97091, 78423), tuple(76536, 86761), tuple(10682, 27325), tuple(55401, 99488), tuple(34196, 88793), tuple(88024, 37693), tuple(4586, 62614), tuple(74857, 37796), tuple(19724, 59109), tuple(17642, 34748), tuple(87983, 11996), tuple(6814, 68602), tuple(63566, 16836), tuple(21026, 42675), tuple(3528, 81994), tuple(58141, 81954), tuple(79520, 99518), tuple(52627, 62974), tuple(42056, 1000), tuple(85464, 63420), tuple(30434, 86139), tuple(59754, 88493), tuple(41386, 76058), tuple(27894, 78093), tuple(63842, 72458), tuple(6928, 37187), tuple(34478, 5193), tuple(57116, 24009), tuple(24858, 84226), tuple(462, 93589), tuple(86510, 80240), tuple(78044, 98234), tuple(30812, 40060), tuple(423, 46196), tuple(47139, 89017), tuple(26066, 21081), tuple(45463, 37260), tuple(34366, 23814), tuple(45937, 79795), tuple(89975, 20405), tuple(21792, 43980), tuple(13675, 11145), tuple(98902, 47577), tuple(20383, 49241), tuple(97905, 16457), tuple(85839, 23279), tuple(33931, 13532), tuple(91486, 54207), tuple(46981, 41204), tuple(49524, 10080), tuple(21201, 3854), tuple(70178, 71393), tuple(26825, 35670), tuple(91350, 92038), tuple(82297, 81201), tuple(47908, 26073), tuple(6456, 40194), tuple(45104, 62038), tuple(75781, 55421), tuple(49561, 35610), tuple(47838, 93109), tuple(25109, 10837), tuple(16666, 99790), tuple(54882, 29259), tuple(28169, 76030), tuple(99605, 78334), tuple(19151, 86372), tuple(48747, 64053), tuple(78764, 38705), tuple(43762, 3756), tuple(22725, 14026), tuple(85174, 6263), tuple(76327, 1072), tuple(92817, 63030), tuple(59923, 28851), tuple(39614, 77354), tuple(54467, 80792), tuple(37309, 8679), tuple(42247, 28830), tuple(60892, 36834), tuple(54108, 62952), tuple(33682, 52992), tuple(87318, 63605), tuple(3180, 91762), tuple(24774, 12744), tuple(4431, 74084), tuple(11712, 7577), tuple(31451, 18294), tuple(68722, 16450), tuple(52185, 92005), tuple(97312, 33963), tuple(43882, 84266), tuple(39958, 52806), tuple(4759, 32862), tuple(33017, 81530), tuple(88475, 9613), tuple(72656, 43214), tuple(27288, 91542), tuple(67232, 47120), tuple(12714, 59507), tuple(17175, 58197), tuple(1719, 97181), tuple(2806, 5682), tuple(22373, 80608), tuple(72129, 33750), tuple(97168, 75472), tuple(16157, 5484), tuple(93177, 59589), tuple(7019, 19832), tuple(63810, 80313), tuple(23551, 45065), tuple(59657, 37189), tuple(12995, 84512), tuple(44630, 12434), tuple(28833, 8088), tuple(56795, 10570), tuple(22385, 4138), tuple(39502, 41865), tuple(67720, 31597), tuple(54837, 8933), tuple(19906, 12496), tuple(69993, 30745), tuple(94886, 98186), tuple(6474, 37743), tuple(62063, 5596), tuple(52064, 33592), tuple(57476, 84891), tuple(88798, 43044), tuple(55029, 97222), tuple(73911, 11862), tuple(1205, 76381), tuple(13388, 4303), tuple(73635, 55410), tuple(97777, 32985), tuple(94358, 49709), tuple(62607, 76061), tuple(62525, 8598), tuple(10327, 11235), tuple(18778, 991), tuple(16602, 1008), tuple(6311, 36329), tuple(6464, 33473), tuple(71418, 15828), tuple(49777, 9630), tuple(67644, 45616), tuple(97118, 54851), tuple(79498, 75515), tuple(45056, 12838), tuple(51110, 53572), tuple(4941, 80166), tuple(16052, 81909), tuple(24336, 25459), tuple(60437, 70317), tuple(51544, 8762), tuple(44978, 27145), tuple(78113, 27193), tuple(45148, 7278), tuple(78858, 90800), tuple(29864, 14191), tuple(67835, 78395), tuple(45893, 74512), tuple(81523, 270), tuple(51436, 75334), tuple(39456, 65552), tuple(89548, 42368), tuple(8953, 17953), tuple(47296, 52855), tuple(36236, 70545), tuple(99705, 30645), tuple(58038, 43017), tuple(95851, 60592), tuple(50658, 98282), tuple(48614, 74538), tuple(29026, 6898), tuple(57506, 97917), tuple(33553, 11205), tuple(92292, 53328), tuple(37861, 10865), tuple(70306, 43839), tuple(52283, 94600), tuple(68802, 95126), tuple(92765, 91310), tuple(2574, 45229), tuple(12463, 45681), tuple(73331, 83847), tuple(22565, 66014), tuple(52454, 22571), tuple(17530, 55911), tuple(7358, 36106), tuple(54186, 27674), tuple(55476, 166), tuple(12926, 8902), tuple(63782, 1616), tuple(60085, 35021), tuple(86605, 99026), tuple(7432, 57161), tuple(37268, 11832), tuple(3860, 95662), tuple(30339, 54518), tuple(26163, 96043), tuple(26092, 71977), tuple(63899, 7792), tuple(9804, 66302), tuple(81779, 54515), tuple(2861, 42418), tuple(44736, 75647), tuple(50912, 53848), tuple(72120, 3651), tuple(91526, 72999), tuple(71642, 69795), tuple(40664, 37695), tuple(57357, 83958), tuple(41666, 52277), tuple(49209, 99223), tuple(47274, 75571), tuple(64326, 88981), tuple(67848, 52903), tuple(44013, 43796), tuple(21678, 8103), tuple(74827, 132), tuple(88279, 49672), tuple(10747, 85149), tuple(74506, 99115), tuple(89615, 95102), tuple(14077, 79858), tuple(55139, 17814), tuple(5519, 48761), tuple(62278, 39931), tuple(58406, 38267), tuple(58705, 86071), tuple(63443, 11013), tuple(53144, 22114), tuple(78535, 70561), tuple(85423, 36012), tuple(3285, 72479), tuple(73658, 19340), tuple(18511, 10477), tuple(60780, 75674), tuple(88032, 88205), tuple(35386, 23855), tuple(49977, 32673), tuple(93206, 71515), tuple(3482, 73115), tuple(48423, 52857), tuple(11899, 30649), tuple(59730, 15323), tuple(89442, 87402), tuple(439, 50184), tuple(98106, 42819), tuple(25941, 82842), tuple(82980, 56368), tuple(71420, 11196), tuple(20860, 78799), tuple(71131, 53182), tuple(45795, 85122), tuple(34635, 83218), tuple(78160, 79377), tuple(8534, 26595), tuple(35248, 17819), tuple(54060, 99480), tuple(36087, 84130), tuple(16001, 59701), tuple(63490, 15318), tuple(41259, 62966), tuple(79583, 94979), tuple(49892, 92957), tuple(8542, 94075), tuple(66339, 33975), tuple(21084, 67889), tuple(14718, 20930), tuple(1760, 60204), tuple(42318, 36873), tuple(2306, 42786), tuple(1667, 59179), tuple(29425, 64430), tuple(64436, 4268), tuple(52666, 79958), tuple(11248, 35590), tuple(37352, 72786), tuple(79273, 24409), tuple(47965, 59976), tuple(61729, 87562), tuple(22673, 52091), tuple(58668, 33485), tuple(60556, 6194), tuple(9974, 17532), tuple(91645, 12490), tuple(16690, 75552), tuple(30983, 79572), tuple(73896, 87577), tuple(82325, 6966), tuple(46769, 19266), tuple(6691, 2816), tuple(65074, 51276), tuple(83174, 210), tuple(38395, 19191), tuple(83871, 939), tuple(9543, 23700), tuple(18316, 3882), tuple(18604, 6191), tuple(53431, 2917), tuple(71291, 3352), tuple(46424, 29885), tuple(44395, 57382), tuple(95028, 33049), tuple(96372, 2057), tuple(26911, 14241), tuple(35535, 27007), tuple(25527, 36480), tuple(13612, 95407), tuple(56176, 82284), tuple(28597, 48562), tuple(76438, 43785), tuple(17631, 15131), tuple(18728, 76676), tuple(49606, 60663), tuple(64878, 57243), tuple(10925, 14798), tuple(72592, 95876), tuple(8144, 58293), tuple(36923, 57214), tuple(82893, 42678), tuple(15533, 63570), tuple(66619, 96607), tuple(32491, 70158), tuple(25175, 70456), tuple(54365, 64639), tuple(56529, 44275), tuple(85598, 13051), tuple(82052, 78051), tuple(6802, 14950), tuple(18964, 77404), tuple(69285, 33899), tuple(42496, 817), tuple(80092, 73354), tuple(44095, 57405), tuple(6715, 98298), tuple(82698, 65201), tuple(25536, 48241), tuple(60721, 38389), tuple(72591, 3716), tuple(76974, 58694), tuple(39723, 66127), tuple(21781, 27885), tuple(57871, 26565), tuple(57327, 1713), tuple(43406, 68141), tuple(65690, 21025), tuple(77459, 59220), tuple(78038, 40571), tuple(44248, 86386), tuple(17714, 38469), tuple(14993, 99711), tuple(18231, 62648), tuple(8081, 2797), tuple(73996, 60186), tuple(98808, 9291), tuple(93219, 32512), tuple(45831, 71316), tuple(9315, 81476), tuple(31933, 97130), tuple(20920, 2404), tuple(31015, 11982), tuple(1251, 81196), tuple(35575, 4027), tuple(81650, 61732), tuple(10241, 79907), tuple(53046, 95973), tuple(68668, 48509), tuple(656, 1992), tuple(10061, 89424), tuple(11047, 71227), tuple(10089, 90496), tuple(57613, 95766), tuple(38775, 44707), tuple(10140, 62292), tuple(91276, 50321), tuple(75890, 59520), tuple(32977, 39392), tuple(43150, 88441), tuple(51314, 81453), tuple(57440, 53885), tuple(85712, 10329), tuple(52723, 17377), tuple(29648, 83895), tuple(41142, 80706), tuple(4167, 43740), tuple(49249, 91247), tuple(15721, 53638), tuple(95764, 35654), tuple(21318, 81252), tuple(97676, 77111), tuple(27613, 35504), tuple(20973, 47975), tuple(60292, 36376), tuple(78092, 59608), tuple(53682, 29368), tuple(95342, 22174), tuple(2289, 80842), tuple(97276, 49917), tuple(21421, 37624), tuple(50678, 98609), tuple(49240, 25174), tuple(64603, 13614), tuple(75402, 61541), tuple(80112, 45397), tuple(14289, 87479), tuple(16888, 98577), tuple(14999, 80972), tuple(64689, 57967), tuple(79391, 54976), tuple(37446, 39412), tuple(86682, 70785), + tuple(21709, 57340), tuple(53757, 39880), tuple(33201, 94136), tuple(27854, 30229), tuple(14865, 56637), tuple(75573, 68915), tuple(84594, 1520), tuple(71261, 69867), tuple(84203, 43708), tuple(76407, 88476), tuple(84395, 77050), tuple(53934, 83635), tuple(32870, 27302), tuple(46646, 46399), tuple(26417, 60940), tuple(87513, 88720), tuple(12542, 32018), tuple(45969, 62284), tuple(26733, 90539), tuple(50556, 13388), tuple(60882, 56222), tuple(48253, 22792), tuple(68209, 18501), tuple(58073, 48960), tuple(6360, 4482), tuple(53997, 31868), tuple(15727, 78331), tuple(81299, 84008), tuple(99495, 89688), tuple(504, 3147), tuple(93985, 77265), tuple(78723, 60673), tuple(30278, 63220), tuple(33434, 26642), tuple(71481, 73333), tuple(49805, 59269), tuple(90657, 93630), tuple(28814, 83954), tuple(91466, 63542), tuple(43843, 69657), tuple(11466, 24136), tuple(63826, 6209), tuple(29687, 95777), tuple(65616, 74144), tuple(62798, 883), tuple(54174, 88934), tuple(35129, 40939), tuple(42224, 54784), tuple(80876, 68479), tuple(80812, 51383), tuple(39443, 11689), tuple(15438, 66488), tuple(32856, 96950), tuple(80525, 99128), tuple(25968, 28334), tuple(91925, 37414), tuple(84823, 58164), tuple(17795, 78409), tuple(29912, 53931), tuple(1369, 92329), tuple(36176, 34133), tuple(79057, 62016), tuple(74457, 51743), tuple(90604, 95280), tuple(18107, 81811), tuple(26994, 78521), tuple(4762, 53724), tuple(8229, 90056), tuple(60962, 1202), tuple(80485, 44934), tuple(58917, 36716), tuple(71770, 42524), tuple(94551, 98259), tuple(39500, 41373), tuple(50410, 70615), tuple(63782, 25832), tuple(74940, 15450), tuple(90724, 44531), tuple(69088, 22535), tuple(40581, 3354), tuple(1756, 86005), tuple(93128, 31200), tuple(14139, 8370), tuple(65646, 40141), tuple(31537, 89271), tuple(7635, 66721), tuple(67463, 97745), tuple(12391, 36807), tuple(6311, 30232), tuple(20818, 91220), tuple(53449, 11632), tuple(21802, 93687), tuple(75581, 79739), tuple(5514, 57540), tuple(67063, 99383), tuple(98230, 18983), tuple(50929, 35978), tuple(16069, 59906), tuple(93594, 94696), tuple(13344, 34575), tuple(30331, 84457), tuple(78047, 97558), tuple(5507, 41722), tuple(81016, 8762), tuple(91323, 59598), tuple(67184, 8555), tuple(76659, 67276), tuple(6511, 94844), tuple(1063, 39110), tuple(40795, 16854), tuple(40694, 32666), tuple(14734, 95257), tuple(6818, 30227), tuple(32211, 56294), tuple(31129, 97716), tuple(93866, 6117), tuple(42144, 91974), tuple(64560, 9708), tuple(5803, 92811), tuple(7240, 42166), tuple(97514, 19116), tuple(59904, 64965), tuple(73031, 69137), tuple(63313, 82886), tuple(58529, 84361), tuple(47365, 96118), tuple(27999, 83969), tuple(98211, 52135), tuple(86460, 86408), tuple(21315, 59646), tuple(98469, 99928), tuple(24453, 79050), tuple(97595, 41780), tuple(35575, 22842), tuple(18219, 72673), tuple(4001, 89495), tuple(19563, 18097), tuple(566, 5304), tuple(37517, 63100), tuple(11251, 58908), tuple(2474, 55788), tuple(83078, 65059), tuple(68185, 94587), tuple(33305, 36706), tuple(81350, 72951), tuple(37115, 41580), tuple(6005, 44393), tuple(4318, 67309), tuple(21346, 75943), tuple(57955, 33395), tuple(75723, 89514), tuple(2661, 42938), tuple(89643, 48828), + tuple(3409, 13157), tuple(13667, 78006), tuple(56518, 86796), tuple(38971, 28234), tuple(38060, 77284), tuple(68626, 83168), tuple(69324, 67649), tuple(48994, 40388), tuple(87024, 14379), tuple(12475, 27192), tuple(41271, 41939), tuple(50304, 38146), tuple(8682, 25307), tuple(93898, 48129), tuple(34600, 25005), tuple(48022, 22298), tuple(25683, 46046), tuple(24839, 69086), tuple(50505, 93439), tuple(90497, 50297), tuple(16054, 68182), tuple(69768, 67239), tuple(35909, 84118), tuple(64986, 21267), tuple(32550, 33801), tuple(8884, 66830), tuple(10690, 75679), tuple(59327, 9389), tuple(16594, 37706), tuple(54110, 76448), tuple(22052, 90416), tuple(18104, 20971), tuple(78917, 19589), tuple(48799, 38897), tuple(55663, 11112), tuple(24255, 19761), tuple(90224, 59023), tuple(51893, 61626), tuple(57840, 2070), tuple(37436, 84968), tuple(55242, 52606), tuple(71391, 70783), tuple(84796, 72467), tuple(61673, 90112), tuple(61880, 10015), tuple(84560, 21382), tuple(91734, 52105), tuple(94237, 68942), tuple(36055, 26633), tuple(43694, 33404), tuple(60266, 17069), tuple(63045, 2539), tuple(39314, 49430), tuple(66845, 42602), tuple(76834, 50742), tuple(26684, 64231), tuple(83102, 88337), tuple(43541, 16088), tuple(53516, 23759), tuple(21092, 43649), tuple(71242, 31515), tuple(62253, 81538), tuple(19670, 48947), tuple(24097, 83600), tuple(11636, 70960), tuple(55314, 99976), tuple(56296, 68456), tuple(25537, 64586), tuple(45649, 53747), tuple(9712, 85370), tuple(82073, 71622), tuple(97381, 26322), tuple(4927, 47703), tuple(8999, 33464), tuple(5875, 80932), tuple(88591, 63062), tuple(40824, 93164), tuple(55753, 10733), tuple(56196, 8875), tuple(13427, 66714), tuple(22780, 69557), tuple(37212, 13763), tuple(61668, 95614), tuple(79050, 55391), tuple(92892, 94037), tuple(4942, 23252), tuple(34025, 31194), tuple(96074, 59364), tuple(11520, 11652), tuple(94439, 19618), tuple(64758, 41196), tuple(73397, 72389), tuple(57282, 73894), tuple(79700, 78450), tuple(65052, 54392), tuple(72453, 23422), tuple(49093, 48337), tuple(9863, 89449), tuple(60397, 40836), tuple(18147, 51195), tuple(39787, 61479), tuple(63062, 62242), tuple(67547, 5426), tuple(25316, 76298), tuple(16168, 12116), tuple(91884, 94406), tuple(57385, 89464), tuple(93062, 71189), tuple(97612, 38802), tuple(85128, 1852), tuple(80643, 41827), tuple(59109, 50692), tuple(28077, 24715), tuple(67583, 40643), tuple(54073, 32408), tuple(97704, 17820), tuple(15884, 69143), tuple(66420, 36961), tuple(60442, 34685), tuple(3109, 47213), tuple(27157, 42282), tuple(18909, 52184), tuple(16638, 51215), tuple(66044, 40079), tuple(67856, 15021), tuple(26942, 58162), tuple(76866, 73547), tuple(3999, 47414), tuple(5114, 74975), tuple(85820, 10632), tuple(71972, 59810), tuple(66488, 16840), tuple(50779, 93807), tuple(40068, 12260), tuple(67715, 72553), tuple(45275, 57705), tuple(45019, 86665), tuple(97033, 97611), tuple(69136, 54593), tuple(1879, 87594), tuple(49292, 92238), tuple(69064, 7240), tuple(60753, 5294), tuple(36350, 67918), tuple(48440, 43264), tuple(70554, 79751), tuple(40310, 64039), tuple(48171, 75441), tuple(53305, 72396), tuple(44027, 58150), tuple(67485, 38325), tuple(87333, 75101), tuple(2509, 54526), tuple(40794, 18097), tuple(17674, 84451), tuple(30175, 65221), tuple(71744, 57300), tuple(91603, 35695), tuple(33369, 1387), tuple(51808, 2008), tuple(42659, 11574), tuple(39492, 79947), tuple(95089, 47048), tuple(57022, 73399), tuple(72707, 8845), tuple(66843, 61434), tuple(7174, 16342), tuple(50709, 76713), tuple(45560, 1378), tuple(80907, 97774), tuple(651, 93255), tuple(42650, 82788), tuple(2875, 24267), tuple(73437, 67551), tuple(6685, 81749), tuple(43495, 12190), tuple(63932, 69464), tuple(86694, 91717), tuple(91608, 59712), tuple(50833, 91382), tuple(18301, 39265), tuple(48304, 34276), tuple(24633, 56311), tuple(10463, 40342), tuple(17645, 64242), tuple(52245, 96838), tuple(6606, 87413), tuple(75088, 39449), tuple(6247, 97599), tuple(57124, 39047), tuple(49579, 80395), tuple(52959, 14523), tuple(73129, 3675), tuple(78880, 16111), tuple(90870, 27122), tuple(11166, 67671), tuple(48048, 41486), tuple(65329, 98702), tuple(4801, 92915), tuple(88765, 51873), tuple(59370, 1440), tuple(41316, 88008), tuple(92238, 79140), tuple(18523, 32178), tuple(36124, 49818), tuple(84251, 37274), tuple(92085, 96091), tuple(65382, 7189), tuple(30130, 32066), tuple(86434, 46207), tuple(5500, 11160), tuple(88366, 36983), tuple(48685, 47634), tuple(93314, 57448), tuple(95978, 97924), tuple(20017, 85908), tuple(82568, 31256), tuple(44633, 78762), tuple(41625, 11793), tuple(77646, 2315), tuple(67604, 29898), tuple(1492, 55783), tuple(33177, 5891), tuple(93884, 41363), tuple(90527, 43977), tuple(36905, 59152), tuple(37750, 19264), tuple(58020, 1360), tuple(22974, 3246), tuple(41403, 80614), tuple(4479, 37045), tuple(27477, 47093), tuple(79899, 65264), tuple(12625, 46993), tuple(78884, 10896), tuple(49043, 36064), tuple(22725, 18991), tuple(4279, 11656), tuple(58193, 27118), tuple(48315, 26221), tuple(86372, 4638), tuple(86413, 43777), tuple(74216, 60197), tuple(89547, 68700), tuple(618, 62861), tuple(88483, 17054), tuple(59378, 75565), tuple(15001, 59042), tuple(15858, 10735), tuple(42583, 57159), tuple(27836, 12597), tuple(87465, 37449), tuple(95717, 59515), tuple(63369, 36932), tuple(14736, 61367), tuple(14779, 30481), tuple(33108, 95749), tuple(5304, 7878), tuple(74344, 65457), tuple(3519, 98197), tuple(34669, 96365), tuple(31376, 21260), tuple(75715, 11580), tuple(14317, 29528), tuple(10151, 13185), tuple(6975, 59407), tuple(7910, 71250), tuple(21761, 8936), tuple(11683, 43452), tuple(97556, 87506), tuple(87371, 16179), tuple(46806, 74511), tuple(737, 82723), tuple(1197, 77799), tuple(9835, 85745), tuple(66026, 16556), tuple(24784, 20015), tuple(53234, 58687), tuple(4393, 27429), tuple(11484, 48640), tuple(24376, 998), tuple(76115, 38), tuple(72364, 3765), tuple(97109, 9842), tuple(36814, 37745), tuple(58829, 16139), tuple(4165, 93524), tuple(51052, 5215), tuple(69771, 11456), tuple(13263, 75724), tuple(60779, 11359), tuple(9924, 2846), tuple(70887, 4526), tuple(66054, 93309), tuple(15486, 40658), tuple(18780, 1579), tuple(89386, 24351), tuple(33682, 62095), tuple(661, 84125), tuple(13480, 97300), tuple(2408, 25599), tuple(99168, 10687), tuple(84860, 17842), tuple(38292, 12704), tuple(97468, 83719), tuple(38360, 25940), tuple(97314, 65483), tuple(95688, 44394), tuple(47420, 96156), tuple(66394, 61773), tuple(98637, 46400), tuple(69962, 57775), tuple(83857, 45874), tuple(74811, 5741), tuple(96157, 62317), tuple(57902, 79905), tuple(73760, 21345), tuple(58109, 65145), tuple(58678, 5406), tuple(96538, 16329), tuple(42244, 63758), tuple(17613, 66642), tuple(72398, 5307), tuple(12872, 94227), tuple(65046, 1439), tuple(90217, 10756), tuple(58185, 63169), tuple(50247, 86728), tuple(98822, 4390), tuple(82566, 26006), tuple(3574, 42077), tuple(43701, 59837), tuple(85579, 48641), tuple(47792, 34429), tuple(77410, 8515), tuple(97749, 11160), tuple(57462, 33927), tuple(32836, 57768), tuple(26898, 80133), tuple(52210, 57444), tuple(33639, 288), tuple(30309, 29233), tuple(14867, 24307), tuple(67420, 29214), tuple(29889, 86125), tuple(68662, 93027), tuple(30716, 64262), tuple(9145, 66627), tuple(83817, 78000), tuple(49074, 52390), tuple(52974, 72121), tuple(84006, 2545), tuple(27803, 68907), tuple(79008, 5828), tuple(74872, 89207), tuple(26302, 23622), tuple(26263, 25254), tuple(65652, 38273), tuple(11673, 21629), tuple(70494, 86207), tuple(59074, 85729), tuple(2011, 38108), tuple(70239, 9100), tuple(37062, 67038), tuple(52681, 44407), tuple(79718, 59481), tuple(39506, 32648), tuple(76903, 76789), tuple(45162, 63035), tuple(13344, 3835), tuple(96239, 59063), tuple(24507, 82181), tuple(77403, 89247), tuple(73887, 41747), tuple(5639, 27352), tuple(46718, 96169), tuple(94630, 83108), tuple(37999, 68318), tuple(97717, 53272), tuple(80506, 42486), tuple(7677, 75413), tuple(45129, 2230), tuple(11721, 21720), tuple(88499, 48784), tuple(23501, 58439), tuple(70767, 72086), tuple(78533, 90007), tuple(72580, 80411), tuple(36564, 98451), tuple(89444, 69448), tuple(48038, 26523), tuple(5123, 78026), tuple(29168, 41429), tuple(36287, 72619), tuple(75350, 27908), tuple(7381, 96048), tuple(30090, 51055), tuple(73670, 11691), tuple(39082, 72957), tuple(84785, 52400), tuple(80436, 94637), tuple(17776, 61224), tuple(36848, 71607), tuple(90182, 50522), tuple(78350, 71698), tuple(91120, 27247), tuple(39638, 38298), tuple(22945, 23976), tuple(52034, 72847), tuple(97888, 33382), tuple(20825, 5844), tuple(303, 5273), tuple(62672, 96465), tuple(46951, 93410), tuple(57258, 108), tuple(11116, 34876), tuple(40588, 20691), tuple(61906, 68626), tuple(48319, 90189), tuple(20255, 4601), tuple(80998, 30793), tuple(28741, 2714), tuple(42195, 25873), tuple(17046, 46739), tuple(15319, 54014), tuple(11773, 11673), tuple(73012, 41575), tuple(21747, 59925), tuple(16088, 24272), tuple(38326, 8140), tuple(68006, 23594), tuple(78052, 77991), tuple(45820, 79226), tuple(11143, 88881), tuple(59251, 76272), tuple(18953, 10412), tuple(67075, 57195), tuple(1386, 54226), tuple(42759, 59791), tuple(5696, 15215), tuple(79633, 55487), tuple(3546, 11417), tuple(97976, 8323), tuple(55197, 53843), tuple(12182, 16579), tuple(55706, 87702), tuple(88871, 45930), tuple(98978, 50942), tuple(55874, 87465), tuple(53256, 28916), tuple(90605, 43673), tuple(23906, 75994), tuple(12746, 66785), tuple(91372, 53574), tuple(72302, 69561), tuple(38833, 59338), tuple(98528, 22616), tuple(10045, 25111), tuple(34397, 69161), tuple(86106, 23720), tuple(82705, 67810), tuple(48691, 14861), tuple(41392, 64552), tuple(83105, 6557), tuple(62123, 39827), tuple(94840, 54871), tuple(35778, 26572), tuple(16194, 14615), tuple(27, 8380), tuple(33704, 44750), tuple(86884, 51173), tuple(60330, 80082), tuple(56180, 47098), tuple(6249, 36349), tuple(32268, 12733), tuple(86808, 40162), tuple(27643, 75454), tuple(36783, 30874), tuple(54827, 7607), tuple(54697, 57582), tuple(83316, 18631), + tuple(44081, 33952), tuple(89780, 86498), tuple(63456, 27382), tuple(5654, 13927), tuple(41301, 35640), tuple(4502, 70840), tuple(4238, 62879), tuple(66516, 67091), tuple(96156, 8355), tuple(2902, 23789), tuple(98837, 77623), tuple(86898, 91764), tuple(75147, 6127), tuple(8274, 46182), tuple(7422, 18222), tuple(86509, 25754), tuple(72400, 55881), tuple(84459, 68079), tuple(5654, 76270), tuple(43017, 78770), tuple(45609, 55504), tuple(67256, 51832), tuple(42204, 15653), tuple(52363, 44095), tuple(11760, 24927), tuple(53286, 20903), tuple(97482, 76094), tuple(43809, 8144), tuple(82974, 74859), tuple(65921, 42364), tuple(11938, 55421), tuple(92195, 10809), tuple(91371, 77402), tuple(17644, 86490), tuple(4424, 27504), tuple(56380, 99969), tuple(1731, 80243), tuple(8879, 23354), tuple(94574, 42743), tuple(78875, 2965), tuple(1029, 61788), tuple(64768, 61914), tuple(54149, 90155), tuple(83048, 46305), tuple(80640, 10062), tuple(12372, 94961), tuple(84549, 84061), tuple(99122, 78998), tuple(91039, 95054), tuple(19628, 18651), tuple(52348, 42569), tuple(58086, 76882), tuple(49881, 13151), tuple(8064, 47655), tuple(4457, 63438), tuple(35500, 82994), tuple(47962, 43653), tuple(5050, 36247), tuple(96631, 67316), tuple(49101, 96157), tuple(15785, 96404), tuple(56283, 36312), tuple(31695, 24307), tuple(81897, 59720), tuple(51016, 45776), tuple(92118, 47354), tuple(16024, 38406), tuple(57737, 68887), tuple(28408, 46608), tuple(65055, 1161), tuple(60430, 21682), tuple(22659, 74001), tuple(35202, 60211), tuple(38308, 52926), tuple(74264, 26330), tuple(17038, 41144), tuple(27775, 24875), tuple(49666, 73774), tuple(28516, 34297), tuple(21873, 11504), tuple(3676, 38168), tuple(90003, 25107), tuple(45103, 7031), tuple(71883, 40867), tuple(6274, 71251), tuple(60307, 49056), tuple(58402, 76742), tuple(10010, 36003), tuple(67059, 75300), tuple(36996, 57460), tuple(61413, 54691), tuple(99608, 49572), tuple(87512, 44123), tuple(43942, 87151), tuple(18543, 43029), tuple(886, 83140), tuple(75529, 69749), tuple(54090, 8088), tuple(43094, 35468), tuple(76460, 45310), tuple(64690, 46953), tuple(29561, 93370), tuple(97598, 21618), tuple(28166, 8888), tuple(12234, 771), tuple(65670, 1561), tuple(85467, 97276), tuple(98868, 57050), tuple(14619, 53684), tuple(924, 82181), tuple(65602, 36977), tuple(7888, 8938), tuple(32792, 1046), tuple(18719, 99863), tuple(34993, 11678), tuple(28837, 64924), tuple(83079, 48559), tuple(5806, 92117), tuple(79239, 8754), tuple(89819, 16162), tuple(99505, 94650), tuple(8636, 27356), tuple(6056, 5682), tuple(1921, 15164), tuple(45536, 10747), tuple(56628, 62991), tuple(51456, 54815), tuple(13030, 47920), tuple(27330, 48623), tuple(21393, 96651), tuple(51282, 5317), tuple(78200, 42975), tuple(18082, 38478), tuple(32594, 4205), tuple(49208, 22593), tuple(80079, 11765), tuple(65186, 60836), tuple(11601, 9377), tuple(95550, 52242), tuple(86838, 96932), tuple(17508, 91440), tuple(73427, 92075), tuple(70969, 37180), tuple(7091, 48708), tuple(35444, 42181), tuple(91735, 29746), tuple(11924, 89935), tuple(34418, 61018), tuple(68065, 96782), tuple(30869, 53390), tuple(99315, 78165), tuple(97205, 90309), tuple(88481, 24681), + tuple(17847, 75359), tuple(73636, 11167), tuple(91431, 62190), tuple(28478, 6770), tuple(97305, 77873), tuple(56987, 22599), tuple(40879, 63647), tuple(1974, 67839), tuple(88651, 99581), tuple(67087, 51740), tuple(24861, 74794), tuple(92730, 14161), tuple(52639, 78795), tuple(37163, 80079), tuple(87445, 7053), tuple(27234, 79447), tuple(43352, 66903), tuple(96267, 10657), tuple(57181, 24266), tuple(84236, 83872), tuple(56551, 30387), tuple(4972, 87269), tuple(98922, 1624), tuple(48398, 19886), tuple(40570, 79648), tuple(92239, 98232), tuple(86789, 55696), tuple(64626, 44726), tuple(82391, 95837), tuple(74414, 93972), tuple(97542, 73957), tuple(76038, 54044), tuple(66087, 24170), tuple(25731, 50138), tuple(39800, 75428), tuple(21730, 88783), tuple(53518, 83466), tuple(50784, 72242), tuple(23969, 85392), tuple(43772, 70437), tuple(87869, 33052), tuple(15531, 61368), tuple(22519, 38591), tuple(37709, 35030), tuple(74030, 5134), tuple(18667, 50524), tuple(84691, 21182), tuple(50932, 66070), tuple(27898, 10408), tuple(79554, 49192), tuple(2517, 7746), tuple(71312, 22108), tuple(15511, 37874), tuple(21623, 77591), tuple(10809, 46240), tuple(40913, 29935), tuple(78969, 56158), tuple(46274, 75491), tuple(87163, 49581), tuple(88417, 86223), tuple(41666, 28061), tuple(17503, 13021), tuple(16476, 50547), tuple(56184, 32943), tuple(89243, 61225), tuple(89844, 81092), tuple(19846, 44485), tuple(25999, 46684), tuple(67283, 76235), tuple(64393, 53397), tuple(41565, 93212), tuple(82296, 54617), tuple(62466, 54078), tuple(97942, 92201), tuple(18205, 67342), tuple(44364, 51466), tuple(72744, 4796), tuple(72526, 68979), tuple(50015, 88033), tuple(19680, 47415), tuple(65486, 46344), tuple(21531, 42236), tuple(3452, 94720), tuple(44902, 89762), tuple(13814, 85842), tuple(98337, 42500), tuple(74870, 31262), tuple(72964, 10884), tuple(64408, 43927), tuple(97024, 66176), tuple(55999, 75231), tuple(72794, 37516), tuple(67787, 70137), tuple(4960, 2377), tuple(22048, 86320), tuple(9964, 86377), tuple(30766, 39958), tuple(68684, 29197), tuple(43864, 72887), tuple(90838, 11639), tuple(97183, 10594), tuple(99649, 22933), tuple(91770, 4554), tuple(97882, 60479), tuple(91041, 72702), tuple(47685, 56715), tuple(51900, 61103), tuple(90821, 27638), tuple(95748, 57574), tuple(79106, 14366), tuple(10560, 97465), tuple(12009, 55707), tuple(65879, 34837), tuple(67934, 69351), tuple(58075, 96424), tuple(26898, 13830), tuple(2074, 46887), tuple(47317, 28361), tuple(97566, 43461), tuple(8150, 8518), tuple(21546, 42240), tuple(75546, 59160), tuple(65267, 35547), tuple(32762, 8539), tuple(31559, 21127), tuple(31913, 36056), tuple(80988, 11524), tuple(41145, 62648), tuple(23225, 40076), tuple(17544, 39206), tuple(1553, 91048), tuple(16940, 78156), tuple(7990, 70275), tuple(14929, 46391), tuple(92515, 27289), tuple(77071, 8542), tuple(29061, 27539), tuple(61002, 28411), tuple(88830, 96749), tuple(52211, 71717), tuple(19450, 46195), tuple(5895, 47099), tuple(29098, 35266), tuple(75499, 90090), tuple(76936, 30217), tuple(97220, 51472), tuple(63272, 35659), tuple(62885, 64591), tuple(95983, 97721), tuple(63118, 93206), tuple(98618, 82875), tuple(89990, 44842), tuple(75664, 44348), tuple(86664, 44960), tuple(50835, 42026), tuple(26637, 6312), tuple(99637, 96642), tuple(59176, 14821), tuple(50542, 9553), tuple(76633, 65029), tuple(25409, 65198), tuple(3352, 69819), tuple(63711, 60406), tuple(95437, 53364), tuple(37840, 77585), tuple(46865, 9097), tuple(19420, 46524), tuple(88308, 21695), tuple(32788, 12773), tuple(42860, 16774), tuple(20890, 85130), tuple(91438, 59944), tuple(18399, 28949), tuple(20946, 76691), tuple(46617, 83686), tuple(34107, 99019), tuple(49597, 44158), tuple(33564, 36586), tuple(87590, 72014), tuple(59107, 18546), tuple(44421, 43424), tuple(21333, 27720), tuple(1135, 18434), tuple(69321, 80520), tuple(28921, 41288), tuple(18914, 53626), tuple(63676, 98378), tuple(29612, 9956), tuple(3908, 2160), tuple(78213, 53772), tuple(45709, 90664), tuple(77042, 41054), tuple(86883, 36641), tuple(99497, 83975), tuple(98822, 39177), tuple(38175, 78142), tuple(8236, 62618), tuple(11422, 92281), tuple(24292, 13446), tuple(14489, 14652), tuple(89100, 73028), tuple(84314, 64770), tuple(93912, 25955), tuple(33612, 87481), tuple(12263, 39940), tuple(38184, 58202), tuple(77635, 79922), tuple(78339, 97371), tuple(47955, 29169), tuple(51554, 40923), tuple(74047, 67244), tuple(85365, 31911), tuple(56786, 6734), tuple(82342, 51354), tuple(82818, 80508), tuple(61409, 85614), tuple(25675, 10634), tuple(17091, 62250), tuple(84446, 23721), tuple(267, 14486), tuple(71998, 69455), tuple(46656, 67266), tuple(32788, 84839), tuple(42014, 98189), tuple(49293, 8851), tuple(66248, 62924), tuple(19458, 74293), tuple(90351, 62521), tuple(83067, 20364), tuple(47665, 30564), tuple(4391, 85292), tuple(96286, 26682), tuple(38393, 19001), tuple(54383, 21667), tuple(57586, 88071), tuple(61809, 69649), tuple(52249, 43209), tuple(43878, 30047), tuple(85943, 32125), tuple(14229, 12697), tuple(92247, 72822), tuple(97179, 86933), tuple(63243, 84200), tuple(42053, 43557), tuple(95748, 9682), tuple(43850, 72883), tuple(3576, 48689), tuple(1517, 48614), tuple(52726, 32475), tuple(93527, 61058), tuple(96804, 21108), tuple(78109, 63584), tuple(23551, 15738), tuple(38196, 68934), tuple(48406, 42638), tuple(52135, 73232), tuple(64063, 91934), tuple(16822, 37151), tuple(14686, 92843), tuple(11115, 26382), tuple(98109, 99834), tuple(86192, 45754), tuple(43093, 97836), tuple(34061, 5654), tuple(71966, 21209), tuple(34289, 45307), tuple(24639, 91324), tuple(58483, 71864), tuple(88435, 91876), tuple(31995, 36723), tuple(60461, 90431), tuple(81765, 37792), tuple(44888, 29738), tuple(76600, 12587), tuple(37134, 48440), tuple(69151, 38382), tuple(51397, 43750), tuple(4293, 98001), tuple(27450, 28456), tuple(99384, 24614), tuple(981, 89456), tuple(59721, 47304), tuple(60616, 98154), tuple(98744, 11293), tuple(83417, 71831), tuple(32729, 41250), tuple(46234, 15350), tuple(39317, 40016), tuple(10667, 89674), tuple(50749, 56788), tuple(2889, 90006), tuple(20397, 68884), tuple(32976, 67095), tuple(72045, 90810), tuple(73914, 29464), tuple(36641, 44630), tuple(21878, 385), tuple(95246, 23783), tuple(57354, 29305), tuple(26745, 84026), tuple(36892, 58119), tuple(1149, 95862), tuple(86209, 56761), tuple(84711, 48878), tuple(25394, 56006), tuple(31581, 30386), tuple(34987, 34411), tuple(41423, 44982), tuple(74735, 61128), tuple(58589, 76665), tuple(42483, 94983), tuple(54883, 69038), tuple(4802, 55544), tuple(47092, 31410), tuple(6642, 91583), tuple(93798, 25259), tuple(58424, 38132), tuple(43946, 97030), tuple(93700, 68673), tuple(99034, 34439), tuple(66998, 75560), tuple(64453, 50462), tuple(12208, 87262), tuple(8175, 69014), tuple(91514, 85630), tuple(23685, 748), tuple(88106, 51369), tuple(27510, 26419), tuple(83983, 5604), tuple(66703, 57061), tuple(72865, 67896), tuple(94029, 2147), tuple(95321, 30188), tuple(24240, 67512), tuple(21532, 29481), tuple(69257, 9492), tuple(59958, 62068), tuple(18491, 93721), tuple(37525, 12039), tuple(95626, 86236), tuple(49136, 11328), tuple(71565, 98832), tuple(77767, 34118), tuple(64925, 21897), tuple(73541, 79422), tuple(92001, 79259), tuple(8309, 34891), tuple(66449, 55242), tuple(85889, 88359), tuple(90559, 87521), tuple(92585, 92004), tuple(21799, 17117), tuple(98134, 53406), tuple(40978, 17010), tuple(55063, 73235), tuple(7601, 13970), tuple(46646, 31351), tuple(7085, 97956), tuple(45998, 98665), tuple(40992, 82168), tuple(4552, 54096), tuple(77766, 7561), tuple(66864, 26750), tuple(88596, 49245), tuple(82930, 33251), tuple(36666, 90013), tuple(71198, 85282), tuple(30600, 59309), tuple(20617, 9735), tuple(96180, 42996), tuple(71846, 84832), tuple(10602, 94421), tuple(83237, 85278), tuple(63713, 14908), tuple(10950, 42931), tuple(33645, 74769), tuple(69501, 8603), tuple(63596, 44221), tuple(75895, 36447), tuple(43990, 4721), tuple(19047, 91357), tuple(35225, 30088), tuple(78898, 87190), tuple(9961, 52820), tuple(6085, 61213), tuple(98275, 84058), tuple(61081, 91315), tuple(28381, 30910), tuple(15828, 72673), tuple(79008, 65337), tuple(60317, 77055), tuple(78534, 50282), tuple(9752, 74831), tuple(62049, 63249), tuple(31455, 74843), tuple(2530, 28581), tuple(68894, 84015), tuple(12791, 14820), tuple(37148, 48411), tuple(88220, 90241), tuple(60582, 70112), tuple(49890, 26900), tuple(94049, 49226), tuple(19582, 98549), tuple(87964, 73614), tuple(54195, 95007), tuple(73593, 29007), tuple(35362, 47461), tuple(93549, 82201), tuple(74305, 49248), tuple(7030, 46073), tuple(69488, 56250), tuple(63045, 25229), tuple(44038, 24680), tuple(65848, 36124), tuple(53985, 95308), tuple(65103, 82209), tuple(26563, 58468), tuple(33153, 12174), tuple(29634, 21978), tuple(26461, 3090), tuple(88683, 4514), tuple(45782, 83561), tuple(56318, 92969), tuple(5587, 61631), tuple(92117, 78865), tuple(78775, 72654), tuple(47395, 49073), tuple(20541, 46928), tuple(71357, 58929), tuple(45184, 76268), tuple(59359, 77092), tuple(5298, 10020), tuple(580, 98499), tuple(9119, 16986), tuple(45518, 86386), tuple(63375, 76589), tuple(31660, 86697), tuple(35851, 65479), tuple(69920, 42815), tuple(30208, 56290), tuple(26343, 37505), tuple(56509, 63902), tuple(85757, 64286), tuple(78627, 79973), tuple(53080, 73913), tuple(49000, 2312), tuple(47315, 57178), tuple(13033, 26209), tuple(53799, 58615), tuple(54508, 22862), tuple(33971, 13889), tuple(22815, 37914), tuple(37426, 99282), tuple(54022, 81696), tuple(17550, 28739), tuple(99122, 99584), tuple(97931, 6054), tuple(46163, 94552), tuple(58328, 70123), tuple(79181, 99242), tuple(64725, 8569), tuple(69146, 39323), tuple(63563, 27537), tuple(96076, 21338), tuple(22936, 20737), tuple(69747, 58505), tuple(52140, 91592), tuple(17198, 19845), tuple(11003, 48066), tuple(1758, 76734), tuple(39891, 17323), tuple(25673, 35578), tuple(83704, 61339), tuple(71674, 51463), tuple(20522, 73773), tuple(37708, 70488), tuple(55492, 76397), tuple(36380, 58022), + tuple(31085, 23886), tuple(84428, 56183), tuple(61034, 65835), tuple(78297, 58728), tuple(992, 11080), tuple(26764, 59393), tuple(3987, 81148), tuple(57894, 50133), tuple(57393, 54819), tuple(639, 83329), tuple(37777, 47517), tuple(15526, 79423), tuple(88248, 9629), tuple(84464, 59890), tuple(56601, 14257), tuple(67283, 14213), tuple(16041, 41528), tuple(43407, 69763), tuple(51687, 8960), tuple(12121, 10409), tuple(60598, 29848), tuple(7839, 25189), tuple(40941, 3224), tuple(96406, 58803), tuple(61378, 82788), tuple(34541, 19703), tuple(98061, 97148), tuple(742, 7655), tuple(61975, 65313), tuple(64854, 93019), tuple(80244, 18168), tuple(92943, 6105), tuple(73969, 74411), tuple(47856, 26644), tuple(94126, 18220), tuple(81074, 61925), tuple(26953, 28483), tuple(65894, 12345), tuple(54749, 51964), tuple(14147, 41570), tuple(47147, 41809), tuple(8340, 35829), tuple(18897, 32342), tuple(36808, 22226), tuple(18644, 68853), tuple(4559, 12594), tuple(96970, 17395), tuple(50909, 77942), tuple(72027, 49411), tuple(98425, 79478), tuple(45899, 24474), tuple(46824, 48975), tuple(15479, 28870), tuple(45397, 76361), tuple(11420, 22096), tuple(74134, 37467), tuple(25579, 59803), tuple(74687, 44244), tuple(71744, 71562), tuple(49666, 32239), tuple(34931, 56027), tuple(50850, 78241), tuple(71040, 91240), tuple(61550, 47475), tuple(26200, 78373), tuple(54646, 87616), tuple(28950, 6489), tuple(51887, 75308), tuple(3912, 42532), tuple(82742, 42016), tuple(94497, 36681), tuple(62494, 3933), tuple(81131, 18766), tuple(51641, 94651), tuple(72285, 53143), tuple(73943, 73716), tuple(66264, 17309), tuple(43156, 99528), tuple(43697, 78216), tuple(84733, 50821), tuple(75899, 63920), tuple(18455, 7660), tuple(30431, 879), tuple(92204, 44911), tuple(30237, 57641), tuple(33407, 98166), tuple(47862, 73576), tuple(68097, 8833), tuple(2454, 49159), tuple(85772, 67530), tuple(19732, 4536), tuple(93827, 39013), tuple(47927, 1682), tuple(69143, 51598), tuple(87471, 99956), tuple(66362, 70450), tuple(34353, 94326), tuple(15692, 81083), tuple(36376, 91470), tuple(71608, 32098), tuple(38115, 56236), tuple(38822, 64266), tuple(87707, 52553), tuple(97973, 23102), tuple(49267, 68907), tuple(22649, 95175), tuple(33001, 75648), tuple(39808, 55971), tuple(5608, 41816), tuple(40313, 20564), tuple(72994, 53489), tuple(16983, 19806), tuple(46114, 57880), tuple(78622, 59284), tuple(78285, 63449), tuple(84552, 19702), tuple(34234, 63531), tuple(50848, 34774), tuple(87144, 18212), tuple(68214, 1005), tuple(60080, 42398), tuple(60514, 65965), tuple(75134, 65529), tuple(74107, 21666), tuple(59817, 68782), tuple(58940, 16958), tuple(19975, 92583), tuple(38480, 83257), tuple(44510, 44997), tuple(59488, 37263), tuple(71209, 47719), tuple(52080, 94252), tuple(87128, 14831), tuple(74001, 37313), tuple(47448, 76625), tuple(20205, 93608), tuple(30249, 75697), tuple(82584, 44654), tuple(54091, 4298), tuple(47736, 84084), tuple(34052, 55781), tuple(76012, 73648), tuple(63204, 52778), tuple(33692, 54616), tuple(91839, 55044), tuple(71674, 28475), tuple(8517, 3272), tuple(35810, 89905), tuple(35146, 62215), tuple(77262, 18227), tuple(34439, 87732), tuple(82690, 83051), + tuple(13687, 19633), tuple(66238, 44809), tuple(53103, 29620), tuple(93365, 87319), tuple(50385, 4755), tuple(89627, 50902), tuple(51790, 15255), tuple(48989, 19631), tuple(16759, 3431), tuple(90814, 19064), tuple(27831, 70254), tuple(75037, 52472), tuple(35010, 24454), tuple(31155, 22730), tuple(87603, 59121), tuple(1323, 23506), tuple(56458, 11866), tuple(21201, 50026), tuple(66671, 36029), tuple(21700, 69519), tuple(85239, 77201), tuple(95141, 57606), tuple(3242, 19997), tuple(52852, 15715), tuple(49676, 70126), tuple(73970, 9214), tuple(86637, 18585), tuple(14571, 65017), tuple(65446, 43663), tuple(20121, 50571), tuple(88634, 87895), tuple(65246, 62716), tuple(27591, 85239), tuple(33623, 14256), tuple(66412, 77902), tuple(16008, 6217), tuple(979, 1666), tuple(22123, 54052), tuple(21596, 7241), tuple(42224, 60675), tuple(23345, 4908), tuple(33780, 16632), tuple(45087, 11756), tuple(10951, 69020), tuple(46138, 47932), tuple(69936, 20048), tuple(5871, 96808), tuple(45595, 67151), tuple(11993, 21010), tuple(20462, 16667), tuple(41417, 88964), tuple(97285, 44958), tuple(20062, 41444), tuple(50808, 18976), tuple(43350, 88847), tuple(34906, 58686), tuple(18132, 2775), tuple(45165, 45298), tuple(75000, 4332), tuple(62157, 9375), tuple(88002, 89214), tuple(84772, 59883), tuple(78078, 35447), tuple(37222, 79319), tuple(43545, 20731), tuple(30761, 13677), tuple(27691, 25767), tuple(97750, 154), tuple(87313, 16187), tuple(78338, 15942), tuple(61168, 16886), tuple(73848, 48436), tuple(74553, 13738), tuple(50645, 37279), tuple(11352, 63404), tuple(85650, 43058), tuple(9553, 2374), tuple(5443, 50670), tuple(55599, 64207), tuple(74136, 41008), tuple(12098, 83456), tuple(98240, 65916), tuple(59743, 64811), tuple(53244, 68834), tuple(66230, 81024), tuple(13734, 83786), tuple(40505, 76939), tuple(93029, 55536), tuple(29943, 53386), tuple(33838, 94514), tuple(71750, 96644), tuple(30017, 8255), tuple(4931, 38730), tuple(2317, 55953), tuple(52389, 67128), tuple(70794, 44324), tuple(24102, 85008), tuple(46435, 65609), tuple(19704, 92026), tuple(99929, 86339), tuple(67622, 13853), tuple(95573, 72963), tuple(99732, 75024), tuple(60437, 5554), tuple(78047, 64444), tuple(95426, 63150), tuple(45798, 26879), tuple(45561, 12951), tuple(95873, 14825), tuple(36695, 13697), tuple(88796, 31855), tuple(52103, 53754), tuple(34496, 56371), tuple(33575, 17436), tuple(39528, 83385), tuple(36153, 48372), tuple(15, 80583), tuple(39015, 36980), tuple(44747, 11011), tuple(7314, 54178), tuple(37252, 52551), tuple(92128, 52377), tuple(66571, 16799), tuple(35841, 92438), tuple(85840, 1365), tuple(39413, 15660), tuple(14759, 58002), tuple(40158, 36685), tuple(68936, 15130), tuple(69488, 30639), tuple(40633, 23355), tuple(93700, 49305), tuple(23456, 96541), tuple(24357, 99667), tuple(25072, 2364), tuple(34734, 17869), tuple(72064, 40226), tuple(22712, 41911), tuple(77545, 19335), tuple(33945, 13408), tuple(63813, 44097), tuple(21816, 77633), tuple(93359, 9036), tuple(47001, 85666), tuple(21934, 56004), tuple(19148, 75033), tuple(88715, 15387), tuple(79158, 53971), tuple(59300, 19502), tuple(66517, 80891), tuple(13859, 63857), tuple(81036, 38595), tuple(8876, 37315), tuple(26819, 54318), tuple(32428, 13471), tuple(2615, 24036), tuple(56894, 82103), tuple(59056, 50983), tuple(15479, 66848), tuple(75766, 27048), tuple(52141, 81023), tuple(94385, 34233), tuple(93361, 79520), tuple(30867, 80795), tuple(46204, 9262), tuple(7946, 4084), tuple(78272, 87422), tuple(33639, 20782), tuple(31276, 45969), tuple(77720, 1335), tuple(16701, 70082), tuple(64963, 19854), tuple(7812, 8856), tuple(16170, 81834), tuple(22877, 7520), tuple(7132, 80996), tuple(1917, 27657), tuple(24737, 91605), tuple(8195, 31354), tuple(22561, 70343), tuple(67166, 74828), tuple(39705, 79118), tuple(43241, 67180), tuple(63526, 22190), tuple(67442, 18172), tuple(38470, 51567), tuple(48664, 43895), tuple(90585, 51544), tuple(11842, 9287), tuple(4231, 61462), tuple(13104, 65739), tuple(52455, 27122), tuple(32318, 92494), tuple(77028, 57920), tuple(52314, 80381), tuple(96749, 22065), tuple(50502, 39753), tuple(99787, 70903), tuple(97786, 28008), tuple(30462, 94898), tuple(59403, 38638), tuple(29827, 16423), tuple(23066, 87865), tuple(61889, 7941), tuple(23948, 78242), tuple(32395, 9480), tuple(36150, 31784), tuple(83146, 10647), tuple(68557, 26863), tuple(93482, 94228), tuple(28512, 89595), tuple(89424, 17693), tuple(68947, 47792), tuple(77918, 25182), tuple(31272, 59863), tuple(10836, 23758), tuple(76913, 75785), tuple(97969, 35902), tuple(55507, 58629), tuple(918, 8356), tuple(66592, 31055), tuple(95309, 59336), tuple(51917, 63380), tuple(79369, 21373), tuple(82766, 76689), tuple(90893, 53940), tuple(31697, 95784), tuple(78683, 89271), tuple(29009, 41573), tuple(9294, 6063), tuple(80573, 79144), tuple(59240, 77056), tuple(99089, 4209), tuple(90406, 92148), tuple(48879, 74391), tuple(22792, 13661), tuple(52282, 74677), tuple(48330, 54418), tuple(6927, 75154), tuple(35007, 12002), tuple(86885, 50845), tuple(74200, 7643), tuple(57915, 3525), tuple(89763, 13455), tuple(98115, 11696), tuple(56291, 17002), tuple(22153, 27947), tuple(85961, 14263), tuple(74214, 58127), tuple(21084, 3965), tuple(86912, 49029), tuple(43018, 83709), tuple(67265, 85823), tuple(68600, 15226), tuple(25932, 81914), tuple(73795, 41791), tuple(3158, 90348), tuple(7664, 81621), tuple(81479, 60118), tuple(93519, 76982), tuple(75440, 3594), tuple(88965, 91886), tuple(92353, 12231), tuple(39378, 69012), tuple(71183, 88536), tuple(36041, 65794), tuple(6724, 26825), tuple(5123, 57858), tuple(2529, 85540), tuple(33448, 94400), tuple(30462, 37765), tuple(30025, 78210), tuple(74349, 5545), tuple(73389, 88842), tuple(78939, 62188), tuple(27948, 62059), tuple(90829, 67200), tuple(44234, 57891), tuple(30700, 61417), tuple(44025, 71190), tuple(22931, 17654), tuple(23476, 87369), tuple(9619, 78967), tuple(24405, 67927), tuple(84754, 91358), tuple(14649, 71404), tuple(4410, 74364), tuple(61417, 87647), tuple(73297, 46647), tuple(32082, 33309), tuple(44590, 47039), tuple(67518, 99908), tuple(22881, 99699), tuple(36657, 17859), tuple(17556, 91128), tuple(58478, 75834), tuple(57048, 73419), tuple(90902, 11840), tuple(4126, 69894), tuple(30361, 54290), tuple(31297, 28595), tuple(54659, 98844), tuple(71265, 86805), tuple(49708, 38180), tuple(24851, 15906), tuple(86094, 67606), tuple(13603, 68975), tuple(3601, 93501), tuple(93480, 17205), tuple(82020, 17859), tuple(68339, 66849), tuple(66423, 9217), tuple(84188, 55471), tuple(28167, 29187), tuple(51166, 46084), tuple(88799, 39664), tuple(67897, 91643), tuple(43015, 68398), tuple(7181, 78174), tuple(6810, 46804), tuple(6034, 55550), tuple(51391, 29469), tuple(76157, 96247), tuple(54973, 75826), tuple(83858, 53576), tuple(87315, 76427), tuple(44051, 44348), tuple(78313, 73128), tuple(44289, 62279), tuple(61897, 87062), tuple(40767, 93761), tuple(91660, 32072), tuple(5223, 36184), tuple(30709, 51066), tuple(40581, 38123), tuple(27886, 39104), tuple(40119, 20754), tuple(27423, 22588), tuple(57235, 49005), tuple(88733, 11711), tuple(4282, 60158), tuple(18632, 3837), tuple(68953, 17510), tuple(21256, 60637), tuple(71727, 176), tuple(25865, 77991), tuple(71032, 40412), tuple(91622, 20288), tuple(49014, 99799), tuple(13599, 5764), tuple(30979, 2454), tuple(40338, 41233), tuple(57336, 50430), tuple(72959, 57286), tuple(85827, 44852), tuple(71907, 33794), tuple(95577, 89084), tuple(72485, 24104), tuple(20306, 76152), tuple(26079, 29381), tuple(46907, 70771), tuple(50365, 90449), tuple(47884, 95986), tuple(88953, 37962), tuple(17407, 91977), tuple(91616, 97270), tuple(85966, 44410), tuple(90389, 12295), tuple(80529, 64553), tuple(21003, 37956), tuple(32923, 30387), tuple(78916, 68050), tuple(15505, 9628), tuple(59050, 38770), tuple(30091, 35499), tuple(30658, 70636), tuple(3160, 24877), tuple(8277, 49676), tuple(74352, 93399), tuple(54074, 53202), tuple(1643, 13321), tuple(71865, 70329), tuple(15251, 5871), tuple(63695, 36988), tuple(96887, 2370), tuple(43098, 14907), tuple(51946, 670), tuple(53294, 72621), tuple(57964, 99634), tuple(17761, 42977), tuple(77571, 38986), tuple(50417, 76385), tuple(80499, 52080), tuple(24301, 56623), tuple(43462, 34196), tuple(49381, 50953), tuple(34053, 74119), tuple(62887, 15142), tuple(69260, 13561), tuple(42848, 87275), tuple(91274, 37268), tuple(87880, 18740), tuple(61314, 8320), tuple(59707, 95633), tuple(38875, 94226), tuple(1415, 62574), tuple(25521, 90678), tuple(48366, 41803), tuple(497, 78256), tuple(26209, 34736), tuple(32946, 44203), tuple(85348, 59409), tuple(25037, 86769), tuple(12753, 78083), tuple(7901, 34859), tuple(70495, 40252), tuple(93318, 95446), tuple(64601, 60123), tuple(18929, 93512), tuple(90647, 85301), tuple(24280, 1900), tuple(82057, 44496), tuple(72227, 33583), tuple(7109, 24591), tuple(37709, 22897), tuple(1237, 16650), tuple(3383, 97434), tuple(72245, 64486), tuple(10201, 46701), tuple(70246, 27545), tuple(98647, 31169), tuple(21901, 75927), tuple(50188, 21441), tuple(89577, 37821), tuple(98823, 69937), tuple(19263, 97734), tuple(92937, 44136), tuple(626, 95680), tuple(12956, 24497), tuple(454, 41351), tuple(40585, 99858), tuple(26190, 82119), tuple(83467, 58869), tuple(39533, 27469), tuple(84276, 26501), tuple(29838, 24478), tuple(78589, 73649), tuple(85241, 37456), tuple(37739, 27890), tuple(30935, 18054), tuple(44388, 47592), tuple(46287, 11414), tuple(41275, 7284), tuple(61172, 59962), tuple(69172, 14436), tuple(11827, 43746), tuple(70455, 93926), tuple(35662, 19338), tuple(24436, 53824), tuple(28435, 33323), tuple(54767, 30980), tuple(91379, 46216), tuple(2656, 98555), tuple(17703, 75278), tuple(52299, 81894), tuple(88460, 76874), tuple(29298, 37649), tuple(87510, 3320), tuple(55513, 94080), tuple(77940, 95554), tuple(15605, 18918), tuple(49452, 85395), tuple(85737, 18109), tuple(73279, 56989), tuple(17461, 32967), tuple(19605, 43424), tuple(93999, 7945), tuple(29865, 94947), tuple(39164, 19448), tuple(88080, 7422), + tuple(436, 99800), tuple(27482, 44994), tuple(73495, 66844), tuple(47160, 66210), tuple(98801, 18553), tuple(33222, 8808), tuple(31037, 15092), tuple(92621, 47184), tuple(54888, 65801), tuple(30873, 33071), tuple(61182, 77132), tuple(81992, 40879), tuple(10268, 38847), tuple(26012, 24149), tuple(85131, 81923), tuple(10950, 55371), tuple(17788, 48443), tuple(39646, 51743), tuple(36019, 76895), tuple(9763, 36927), tuple(19582, 16771), tuple(68211, 84210), tuple(9412, 55904), tuple(44002, 9077), tuple(36583, 1638), tuple(97906, 20583), tuple(12863, 74173), tuple(29698, 34767), tuple(34469, 78263), tuple(87561, 58797), tuple(77844, 10556), tuple(68239, 63155), tuple(41560, 93635), tuple(52548, 95710), tuple(11161, 632), tuple(91657, 97784), tuple(93088, 89618), tuple(42604, 94389), tuple(4198, 51324), tuple(96597, 97093), tuple(77382, 89074), tuple(41381, 89801), tuple(25857, 67775), tuple(41422, 59757), tuple(39574, 93308), tuple(85990, 91621), tuple(49182, 92967), tuple(84187, 73625), tuple(92495, 93334), tuple(12471, 33289), tuple(49105, 76813), tuple(26330, 94103), tuple(70805, 33031), tuple(49193, 18360), tuple(18002, 29159), tuple(70447, 50454), tuple(44081, 3675), tuple(96495, 16455), tuple(98675, 5876), tuple(2913, 30032), tuple(91048, 91939), tuple(50496, 3621), tuple(7244, 20490), tuple(89364, 30152), tuple(43588, 25656), tuple(42086, 70055), tuple(90150, 95763), tuple(31727, 49598), tuple(92625, 29569), tuple(54148, 81753), tuple(77721, 57094), tuple(67706, 83472), tuple(26935, 9073), tuple(29554, 1952), tuple(33394, 13797), tuple(77797, 84190), tuple(65692, 40517), tuple(86640, 91307), tuple(56461, 17709), tuple(30204, 2620), tuple(72787, 87380), tuple(51439, 56294), tuple(25033, 30268), tuple(27379, 59569), tuple(11651, 62401), tuple(69998, 96886), tuple(17278, 56849), tuple(71326, 41808), tuple(50372, 4986), tuple(1711, 73335), tuple(71837, 63661), tuple(78810, 60882), tuple(62918, 6111), tuple(76267, 27414), tuple(12536, 747), tuple(24221, 44906), tuple(2136, 84763), tuple(7736, 18765), tuple(71822, 70209), tuple(55828, 97876), tuple(27029, 80557), tuple(47068, 2260), tuple(47441, 81681), tuple(95204, 83508), tuple(94992, 98690), tuple(86479, 34930), tuple(51759, 64962), tuple(23363, 25795), tuple(50675, 29266), tuple(54059, 35176), tuple(37985, 70844), tuple(270, 33485), tuple(88135, 28988), tuple(97160, 54235), tuple(71087, 50356), tuple(42552, 11173), tuple(58508, 4623), tuple(15663, 61919), tuple(7672, 63865), tuple(14458, 76549), tuple(94036, 65780), tuple(76076, 98795), tuple(65158, 94233), tuple(38869, 33986), tuple(25926, 48043), tuple(8196, 61978), tuple(93547, 83000), tuple(13218, 70869), tuple(40220, 153), tuple(40683, 8335), tuple(38208, 71925), tuple(63199, 70045), tuple(3199, 10537), tuple(16665, 29551), tuple(91333, 59035), tuple(60598, 74055), tuple(18820, 76617), tuple(31822, 14637), tuple(1508, 13279), tuple(99959, 73482), tuple(69854, 34920), tuple(59650, 1074), tuple(1538, 52026), tuple(84941, 6002), tuple(82892, 20921), tuple(88023, 79990), tuple(6945, 92700), tuple(2389, 62469), tuple(38515, 78260), tuple(34721, 56417), tuple(37208, 71058), tuple(78134, 76540), tuple(18831, 53863), + tuple(81277, 26395), tuple(57176, 69906), tuple(55080, 20726), tuple(65843, 9495), tuple(27703, 24879), tuple(60594, 53447), tuple(72896, 95513), tuple(87884, 50244), tuple(25281, 16427), tuple(14122, 6399), tuple(65765, 45679), tuple(38160, 38650), tuple(76820, 91595), tuple(74663, 37143), tuple(35220, 16865), tuple(54664, 88840), tuple(7671, 19781), tuple(7255, 87276), tuple(92182, 47030), tuple(98922, 49381), tuple(21954, 20742), tuple(54674, 19730), tuple(74694, 81672), tuple(31070, 97794), tuple(22759, 3530), tuple(6085, 72621), tuple(17392, 26996), tuple(82220, 41192), tuple(48225, 41272), tuple(42850, 54369), tuple(10817, 25978), tuple(18889, 81907), tuple(33157, 51203), tuple(64325, 5137), tuple(54695, 50597), tuple(32244, 99170), tuple(64264, 23137), tuple(22912, 47267), tuple(70570, 51635), tuple(96224, 20571), tuple(91110, 65969), tuple(2598, 66368), tuple(80926, 52434), tuple(1538, 77141), tuple(10149, 21484), tuple(4981, 58501), tuple(5154, 55414), tuple(66791, 35619), tuple(9905, 90667), tuple(83595, 75525), tuple(31989, 37492), tuple(41740, 48920), tuple(33876, 10878), tuple(48654, 50120), tuple(85890, 46200), tuple(67100, 30387), tuple(76475, 38916), tuple(1654, 1657), tuple(93842, 71472), tuple(14560, 97747), tuple(24866, 74187), tuple(11477, 2492), tuple(94590, 95965), tuple(29363, 58015), tuple(58783, 5304), tuple(27337, 87412), tuple(17695, 41885), tuple(91837, 75700), tuple(271, 49400), tuple(33438, 84607), tuple(78520, 46982), tuple(38817, 66995), tuple(2031, 58147), tuple(80354, 75561), tuple(7752, 55141), tuple(22715, 29219), tuple(10069, 69521), tuple(1711, 23325), tuple(88218, 94290), tuple(44895, 32844), tuple(62152, 964), tuple(32945, 57419), tuple(19030, 51353), tuple(53097, 36525), tuple(76592, 2389), tuple(53949, 27282), tuple(10569, 90204), tuple(94318, 48527), tuple(13855, 27099), tuple(41107, 11962), tuple(39143, 81444), tuple(66004, 38387), tuple(55906, 61394), tuple(34933, 33952), tuple(53868, 82829), tuple(86213, 80445), tuple(40351, 56305), tuple(97656, 90533), tuple(48021, 7262), tuple(49406, 38294), tuple(57170, 7675), tuple(7040, 8039), tuple(65129, 76668), tuple(7554, 74457), tuple(65930, 2421), tuple(12739, 37328), tuple(17174, 68325), tuple(63207, 21315), tuple(70066, 44503), tuple(19112, 8081), tuple(80329, 65152), tuple(76480, 39600), tuple(75262, 45432), tuple(24382, 67054), tuple(75360, 90438), tuple(21786, 19182), tuple(2050, 82428), tuple(34831, 92670), tuple(69746, 44939), tuple(6130, 58630), tuple(62478, 14374), tuple(35730, 71761), tuple(20641, 66145), tuple(86551, 64076), tuple(37559, 79379), tuple(8215, 82203), tuple(33701, 9187), tuple(22679, 38196), tuple(17476, 25994), tuple(4391, 62658), tuple(87726, 32997), tuple(22552, 65818), tuple(18115, 42587), tuple(64374, 97689), tuple(64896, 49572), tuple(98479, 75547), tuple(881, 32287), tuple(25305, 16000), tuple(295, 67454), tuple(67642, 87363), tuple(50945, 31544), tuple(95966, 9972), tuple(44139, 28252), tuple(83682, 88471), tuple(34615, 665), tuple(13190, 85527), tuple(32195, 81130), tuple(22310, 12209), tuple(27910, 60272), tuple(40133, 5905), tuple(29352, 36686), tuple(76443, 64096), tuple(79522, 79616), tuple(63465, 96631), tuple(95604, 90216), tuple(88548, 12411), tuple(63732, 50843), tuple(1478, 11113), tuple(41472, 43329), tuple(35207, 78855), tuple(95093, 22581), tuple(67812, 1348), tuple(96472, 75947), tuple(18984, 63538), tuple(84782, 72178), tuple(53524, 46634), tuple(95525, 15476), tuple(82732, 89272), tuple(59603, 2032), tuple(74431, 78243), tuple(47712, 51835), tuple(82671, 67076), tuple(63302, 96469), tuple(77655, 95524), tuple(11099, 31832), tuple(77967, 32724), tuple(85070, 36190), tuple(93260, 32825), tuple(51348, 34162), tuple(40912, 26841), tuple(27227, 21822), tuple(15979, 96933), tuple(76990, 90541), tuple(36121, 90437), tuple(85571, 9605), tuple(85987, 46881), tuple(86738, 82375), tuple(80188, 48238), tuple(64608, 41916), tuple(79866, 9442), tuple(28100, 95607), tuple(10136, 19628), tuple(6078, 59019), tuple(8971, 11986), tuple(75703, 209), tuple(81982, 98701), tuple(30455, 66367), tuple(92825, 84403), tuple(73144, 4923), tuple(62835, 75533), tuple(90925, 56381), tuple(83853, 86786), tuple(66906, 28576), tuple(69683, 74216), tuple(2171, 22531), tuple(6591, 52559), tuple(59362, 88732), tuple(49865, 38016), tuple(82881, 9151), tuple(71356, 27365), tuple(91463, 45944), tuple(71040, 12264), tuple(62116, 27681), tuple(84941, 82284), tuple(57515, 60713), tuple(45227, 74196), tuple(77502, 17765), tuple(54055, 29484), tuple(33708, 46220), tuple(37344, 75102), tuple(80480, 37942), tuple(95782, 36781), tuple(14092, 82457), tuple(25284, 82297), tuple(85150, 50659), tuple(90037, 99122), tuple(49584, 48321), tuple(8028, 65210), tuple(8162, 32091), tuple(1609, 22211), tuple(38548, 1023), tuple(35864, 43021), tuple(54196, 30754), tuple(88535, 90185), tuple(5518, 97226), tuple(79272, 57758), tuple(61381, 86419), tuple(38344, 86877), tuple(72629, 24694), tuple(12563, 11747), tuple(81456, 44023), tuple(55536, 65195), tuple(67741, 12182), tuple(64250, 29636), tuple(45252, 9834), tuple(16576, 40098), tuple(65924, 11123), tuple(14090, 83443), tuple(95180, 92697), tuple(92452, 7957), tuple(21244, 29717), tuple(50253, 62030), tuple(21401, 70735), tuple(86803, 89625), tuple(17066, 52757), tuple(74570, 89660), tuple(11647, 74336), tuple(22463, 68191), tuple(41693, 67542), tuple(12994, 21955), tuple(3180, 27966), tuple(37236, 51099), tuple(68568, 62778), tuple(2671, 68542), tuple(42771, 4268), tuple(7578, 12919), tuple(33838, 61136), tuple(87904, 48076), tuple(3781, 57164), tuple(83289, 14414), tuple(29626, 91409), tuple(92536, 13946), tuple(88125, 34961), tuple(71541, 41249), tuple(21045, 85183), tuple(21628, 62294), tuple(17768, 22390), tuple(5892, 10231), tuple(85902, 84414), tuple(44078, 87944), tuple(64981, 31018), tuple(85690, 11077), tuple(4711, 9309), tuple(39077, 26339), tuple(85313, 99603), tuple(20267, 31090), tuple(92684, 11726), tuple(17887, 17415), tuple(23064, 83141), tuple(40925, 87246), tuple(17575, 71065), tuple(29396, 86192), tuple(10859, 2881), tuple(50457, 42309), tuple(86972, 41824), tuple(80954, 76970), tuple(11664, 94322), tuple(4286, 93562), tuple(9093, 32589), tuple(81261, 96519), tuple(67886, 3086), tuple(74132, 43197), tuple(94549, 26192), tuple(55498, 75374), tuple(93813, 32911), tuple(6727, 51629), tuple(93543, 55373), tuple(48682, 83316), tuple(32468, 77339), tuple(60028, 4896), tuple(34177, 67214), tuple(35429, 16686), tuple(72814, 39944), tuple(82791, 97364), tuple(21249, 36007), tuple(85536, 84815), tuple(32784, 34349), tuple(2391, 45661), tuple(62595, 30434), tuple(56513, 65051), tuple(22536, 99421), tuple(80603, 62636), tuple(23609, 19082), tuple(33262, 63428), tuple(45307, 96049), tuple(75079, 62835), tuple(52361, 19400), tuple(43845, 89033), tuple(54257, 33298), tuple(31133, 35836), tuple(56725, 10158), tuple(73650, 10456), tuple(77548, 28249), tuple(57998, 79546), tuple(97895, 93196), tuple(472, 18004), tuple(67178, 2684), tuple(34612, 36352), tuple(84970, 98816), tuple(32474, 5895), tuple(60388, 75957), tuple(81643, 26457), tuple(30070, 55744), tuple(14725, 58396), tuple(66451, 69932), tuple(59264, 59569), tuple(98045, 63704), tuple(11925, 87468), tuple(24701, 6280), tuple(47797, 84240), tuple(998, 13575), tuple(37865, 72036), tuple(71339, 10339), tuple(28248, 7481), tuple(33945, 97829), tuple(85194, 8904), tuple(39669, 73192), tuple(24326, 65934), tuple(14438, 72729), tuple(76676, 35176), tuple(97604, 95931), tuple(36032, 61056), tuple(65788, 20291), tuple(73067, 60718), tuple(75742, 27362), tuple(45393, 74792), tuple(49586, 13048), tuple(57961, 68534), tuple(78171, 47271), tuple(76064, 41030), tuple(88738, 10155), tuple(87757, 63134), tuple(95783, 76438), tuple(77935, 85529), tuple(79345, 69555), tuple(94483, 58668), tuple(9432, 40485), tuple(43585, 376), tuple(61737, 97784), tuple(1593, 37078), tuple(11129, 23793), tuple(94341, 64063), tuple(41896, 70446), tuple(77473, 33532), tuple(66748, 65844), tuple(17802, 27920), tuple(22891, 12901), tuple(40435, 43348), tuple(27956, 16989), tuple(29550, 63725), tuple(49453, 61216), tuple(25570, 97985), tuple(39599, 83449), tuple(96373, 12817), tuple(48357, 40473), tuple(99949, 33182), tuple(85434, 45421), tuple(28033, 46182), tuple(80932, 26691), tuple(99522, 29180), tuple(70868, 31903), tuple(63217, 51504), tuple(70267, 29484), tuple(36096, 28371), tuple(45710, 2823), tuple(85697, 3912), tuple(25410, 70358), tuple(73558, 82834), tuple(28617, 80585), tuple(81874, 57512), tuple(76797, 45045), tuple(22091, 84124), tuple(68372, 42189), tuple(66320, 83215), tuple(23013, 22530), tuple(33735, 97800), tuple(54318, 99061), tuple(18025, 39513), tuple(69059, 39780), tuple(58425, 39790), tuple(10222, 96791), tuple(17061, 3138), tuple(92416, 5773), tuple(20023, 31736), tuple(47846, 74511), tuple(52598, 26398), tuple(3738, 44490), tuple(53346, 79223), tuple(31991, 57557), tuple(34592, 98693), tuple(86926, 20881), tuple(14108, 87654), tuple(4889, 34982), tuple(77283, 73201), tuple(13668, 22633), tuple(50763, 95152), tuple(97292, 54613), tuple(22782, 30081), tuple(21536, 46551), tuple(45965, 4172), tuple(75537, 79254), tuple(41267, 86819), tuple(57723, 75200), tuple(60404, 27252), tuple(80305, 57892), tuple(50103, 24015), tuple(69409, 13132), tuple(30717, 56384), tuple(54568, 79877), tuple(8584, 8359), tuple(41416, 64392), tuple(32898, 92944), tuple(5262, 35907), tuple(88652, 77951), tuple(16619, 2797), tuple(42494, 65581), tuple(21009, 18555), tuple(29084, 28068), tuple(29464, 35568), tuple(7288, 52066), tuple(32378, 48725), tuple(95300, 62168), tuple(52295, 97110), tuple(36862, 87786), tuple(12224, 86684), tuple(85883, 34167), tuple(45369, 76651), tuple(95460, 42855), tuple(34354, 87238), tuple(7214, 96375), tuple(58720, 87947), tuple(55009, 10506), tuple(98506, 6081), tuple(46068, 81113), tuple(99065, 58657), tuple(81820, 28081), tuple(90611, 57235), tuple(7661, 72835), tuple(93195, 90418), tuple(34452, 20146), + tuple(39857, 78712), tuple(47185, 52074), tuple(9879, 51807), tuple(92457, 92377), tuple(36082, 17723), tuple(21905, 43398), tuple(35902, 54380), tuple(21791, 6804), tuple(50774, 35200), tuple(11540, 83934), tuple(54574, 57602), tuple(99878, 35568), tuple(28171, 68210), tuple(58132, 17222), tuple(91755, 80585), tuple(18944, 65785), tuple(78535, 70725), tuple(42599, 65291), tuple(62274, 97160), tuple(76487, 23798), tuple(34741, 36988), tuple(7286, 61119), tuple(36824, 29665), tuple(82478, 60722), tuple(90995, 28025), tuple(71438, 40230), tuple(83152, 45104), tuple(1812, 91619)) + + DROP TABLE IF EXISTS test_in diff --git a/tests/queries/0_stateless/00834_kill_mutation.sh b/tests/queries/0_stateless/00834_kill_mutation.sh index 8dbc75be90c..523d01c9405 100755 --- a/tests/queries/0_stateless/00834_kill_mutation.sh +++ b/tests/queries/0_stateless/00834_kill_mutation.sh @@ -45,24 +45,24 @@ ${CLICKHOUSE_CLIENT} --query="ALTER TABLE test.kill_mutation DELETE WHERE x = 1 check_query2="SELECT count() FROM system.mutations WHERE database = 'test' AND table = 'kill_mutation' AND mutation_id = 'mutation_4.txt'" -query_result=`$CLICKHOUSE_CLIENT --query="$check_query1" 2>&1` +query_result=`$CLICKHOUSE_CLIENT --query="$check_query2" 2>&1` while [ "$query_result" == "0" ] do - query_result=`$CLICKHOUSE_CLIENT --query="$check_query1" 2>&1` + query_result=`$CLICKHOUSE_CLIENT --query="$check_query2" 2>&1` sleep 0.5 done -${CLICKHOUSE_CLIENT} --query="SELECT count() FROM system.mutations WHERE database = 'test' AND table = 'kill_mutation' AND mutation_id = 'mutation_4.txt'" +${CLICKHOUSE_CLIENT} --query="SELECT count() FROM system.mutations WHERE database = 'test' AND table = 'kill_mutation' AND mutation_id = 'mutation_4.txt'" # 1 kill_message=$(${CLICKHOUSE_CLIENT} --query="KILL MUTATION WHERE database = 'test' AND table = 'kill_mutation' AND mutation_id = 'mutation_4.txt'") wait -echo "$kill_message" +echo "$kill_message" # waiting test kill_mutation mutation_4.txt DELETE WHERE toUInt32(s) = 1 -${CLICKHOUSE_CLIENT} --query="SELECT * FROM test.kill_mutation" +${CLICKHOUSE_CLIENT} --query="SELECT * FROM test.kill_mutation" # 2001-01-01 2 b # must always be empty ${CLICKHOUSE_CLIENT} --query="SELECT * FROM system.mutations WHERE table = 'kill_mutation' AND database = 'test' AND is_done = 0" diff --git a/tests/queries/0_stateless/00960_live_view_watch_events_live.py b/tests/queries/0_stateless/00960_live_view_watch_events_live.py index 2095683720e..3349175dee8 100755 --- a/tests/queries/0_stateless/00960_live_view_watch_events_live.py +++ b/tests/queries/0_stateless/00960_live_view_watch_events_live.py @@ -30,6 +30,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client1.send('WATCH test.lv EVENTS') + client1.expect('version') client1.expect('1.*' + end_of_block) client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect('2.*' + end_of_block) diff --git a/tests/queries/0_stateless/01398_in_tuple_func.reference b/tests/queries/0_stateless/01398_in_tuple_func.reference new file mode 100644 index 00000000000..1c213bb20d2 --- /dev/null +++ b/tests/queries/0_stateless/01398_in_tuple_func.reference @@ -0,0 +1,13 @@ +1 +1 +1 +1 +1 +1 +1 +0 +1 +1 +1 +0 +1 diff --git a/tests/queries/0_stateless/01398_in_tuple_func.sql b/tests/queries/0_stateless/01398_in_tuple_func.sql new file mode 100644 index 00000000000..1cd5e0cf135 --- /dev/null +++ b/tests/queries/0_stateless/01398_in_tuple_func.sql @@ -0,0 +1,16 @@ +select 1 in tuple(1, 2, 3, 4, 5) settings max_temporary_columns = 2; +select (1, 2) in tuple(tuple(1, 2), tuple(3, 4), tuple(5, 6), tuple(7, 8), tuple(9, 10)) settings max_temporary_columns = 4; + +select 1 in array(1, 2, 3, 4, 5) settings max_temporary_columns = 3; +select (1, 2) in array(tuple(1, 2), tuple(3, 4), tuple(5, 6), tuple(7, 8), tuple(9, 10)) settings max_temporary_columns = 4; + +select (1, 2) in tuple(1, 2); +select (1, 2) in array((1, 3), (1, 2)); +select [1] in array([1], [2, 3]); +select ([1], [2]) in tuple([NULL], [NULL]); +select ([1], [2]) in tuple(([NULL], [NULL]), ([1], [2])); + +select 4 in plus(2, 2); +select (1, 'a') in tuple((1, 'a'), (2, 'b'), (3, 'c')); +select (1, 'a') in tuple((2, 'b'), (3, 'c'), (4, 'd')); +select (1, (2, 'foo')) in tuple((1, (3, 'b')), (1, (2, 'foo'))); diff --git a/tests/queries/0_stateless/01399_http_request_headers.reference b/tests/queries/0_stateless/01399_http_request_headers.reference new file mode 100755 index 00000000000..99ba2b1787f --- /dev/null +++ b/tests/queries/0_stateless/01399_http_request_headers.reference @@ -0,0 +1,10 @@ +1 +Code: 516 +1 +Code: 516 +1 +Code: 516 +processes +Code: 81 +[1] +Code: 73 diff --git a/tests/queries/0_stateless/01399_http_request_headers.sh b/tests/queries/0_stateless/01399_http_request_headers.sh new file mode 100755 index 00000000000..215fb58f012 --- /dev/null +++ b/tests/queries/0_stateless/01399_http_request_headers.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-User: default' -d 'SELECT 1' +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-User: header_test' -d 'SELECT 1' | grep -o 'Code: 516' +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Key: ' -d 'SELECT 1' +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Key: header_test' -d 'SELECT 1' | grep -o 'Code: 516' +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Quota: ' -d 'SELECT 1' +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Quota: header_test' -d 'SELECT 1' | grep -o 'Code: 516' +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Database: system' -d 'SHOW TABLES' | grep -o 'processes' +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Database: header_test' -d 'SHOW TABLES' | grep -o 'Code: 81' +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Format: JSONCompactEachRow' -d 'SELECT 1' | grep -o '\[1\]' +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}" -H 'X-ClickHouse-Format: header_test' -d 'SELECT 1' | grep -o 'Code: 73' diff --git a/tests/queries/0_stateless/01413_rows_events.reference b/tests/queries/0_stateless/01413_rows_events.reference new file mode 100644 index 00000000000..7779d718461 --- /dev/null +++ b/tests/queries/0_stateless/01413_rows_events.reference @@ -0,0 +1,7 @@ +1 +1 +2 +2 +2 2 +3 +3 diff --git a/tests/queries/0_stateless/01413_rows_events.sql b/tests/queries/0_stateless/01413_rows_events.sql new file mode 100644 index 00000000000..375502d4976 --- /dev/null +++ b/tests/queries/0_stateless/01413_rows_events.sql @@ -0,0 +1,31 @@ +DROP TABLE IF EXISTS rows_events_test; +CREATE TABLE rows_events_test (k UInt32, v UInt32) ENGINE = MergeTree ORDER BY k; + +SYSTEM FLUSH LOGS; +TRUNCATE TABLE system.query_log; +INSERT INTO rows_events_test VALUES (1,1); +SYSTEM FLUSH LOGS; +SELECT written_rows FROM system.query_log WHERE query LIKE 'INSERT INTO rows_events_test%' AND type=2; +SELECT value FROM ( + SELECT ProfileEvents.Names as name, ProfileEvents.Values as value FROM system.query_log ARRAY JOIN ProfileEvents WHERE query LIKE 'INSERT INTO rows_events_test%' AND type=2 +) WHERE name='InsertedRows'; + +SYSTEM FLUSH LOGS; +TRUNCATE TABLE system.query_log; +INSERT INTO rows_events_test VALUES (2,2), (3,3); +SYSTEM FLUSH LOGS; +SELECT written_rows FROM system.query_log WHERE query LIKE 'INSERT INTO rows_events_test%' AND type=2; +SELECT value FROM ( + SELECT ProfileEvents.Names as name, ProfileEvents.Values as value FROM system.query_log ARRAY JOIN ProfileEvents WHERE query LIKE 'INSERT INTO rows_events_test%' AND type=2 +) WHERE name='InsertedRows'; + +SYSTEM FLUSH LOGS; +TRUNCATE TABLE system.query_log; +SELECT * FROM rows_events_test WHERE v = 2; +SYSTEM FLUSH LOGS; +SELECT read_rows FROM system.query_log WHERE query LIKE 'SELECT * FROM rows_events_test%' AND type=2; +SELECT value FROM ( + SELECT ProfileEvents.Names as name, ProfileEvents.Values as value FROM system.query_log ARRAY JOIN ProfileEvents WHERE query LIKE 'SELECT * FROM rows_events_test%' AND type=2 +) WHERE name='SelectedRows'; + +DROP TABLE rows_events_test; diff --git a/tests/queries/0_stateless/01418_query_scope_constants_and_remote.reference b/tests/queries/0_stateless/01418_query_scope_constants_and_remote.reference new file mode 100644 index 00000000000..627e1097cda --- /dev/null +++ b/tests/queries/0_stateless/01418_query_scope_constants_and_remote.reference @@ -0,0 +1,5 @@ +1 +1 +1 +1 +1 diff --git a/tests/queries/0_stateless/01418_query_scope_constants_and_remote.sql b/tests/queries/0_stateless/01418_query_scope_constants_and_remote.sql new file mode 100644 index 00000000000..fcdf2f7896e --- /dev/null +++ b/tests/queries/0_stateless/01418_query_scope_constants_and_remote.sql @@ -0,0 +1,3 @@ +select c >= 0 from (SELECT randConstant() as c FROM remote('127.0.0.{1,2}', numbers_mt(1))); +select c >= 0 from (SELECT randConstant() as c FROM remote('127.0.0.{3,2}', numbers_mt(1))); +select c >= 0 from (SELECT randConstant() as c FROM remote('127.0.0.1', numbers_mt(1))); \ No newline at end of file diff --git a/tests/testflows/rbac/requirements/requirements.md b/tests/testflows/rbac/requirements/requirements.md index e679b6b7fec..5590853c9a0 100644 --- a/tests/testflows/rbac/requirements/requirements.md +++ b/tests/testflows/rbac/requirements/requirements.md @@ -439,8 +439,8 @@ hosted in a Gitlab repository. All the updates are tracked using the [Git]'s revision history. -* Gitlab repository: https://gitlab.com/altinity-qa/documents/qa-srs006-clickhouse-role-based-access-control/blob/master/QA_SRS006_ClickHouse_Role_Based_Access_Control.md -* Revision history: https://gitlab.com/altinity-qa/documents/qa-srs006-clickhouse-role-based-access-control/commits/master/QA_SRS006_ClickHouse_Role_Based_Access_Control.md +* GitHub repository: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/rbac/requirements/requirements.md +* Revision history: https://github.com/ClickHouse/ClickHouse/commits/master/tests/testflows/rbac/requirements/requirements.md ## Introduction @@ -3424,15 +3424,15 @@ SHOW [ROW] POLICIES [ON [database.]table] ## References * **ClickHouse:** https://clickhouse.tech -* **Gitlab repository:** https://gitlab.com/altinity-qa/documents/qa-srs006-clickhouse-role-based-access-control/blob/master/QA_SRS006_ClickHouse_Role_Based_Access_Control.md -* **Revision history:** https://gitlab.com/altinity-qa/documents/qa-srs006-clickhouse-role-based-access-control/commits/master/QA_SRS006_ClickHouse_Role_Based_Access_Control.md +* **GitHub repository:** https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/rbac/requirements/requirements.md +* **Revision history:** https://github.com/ClickHouse/ClickHouse/commits/master/tests/testflows/rbac/requirements/requirements.md * **Git:** https://git-scm.com/ * **MySQL:** https://dev.mysql.com/doc/refman/8.0/en/account-management-statements.html * **PostgreSQL:** https://www.postgresql.org/docs/12/user-manag.html [ClickHouse]: https://clickhouse.tech -[Gitlab repository]: https://gitlab.com/altinity-qa/documents/qa-srs006-clickhouse-role-based-access-control/blob/master/QA_SRS006_ClickHouse_Role_Based_Access_Control.md -[Revision history]: https://gitlab.com/altinity-qa/documents/qa-srs006-clickhouse-role-based-access-control/commits/master/QA_SRS006_ClickHouse_Role_Based_Access_Control.md +[GitHub repository]: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/rbac/requirements/requirements.md +[Revision history]: https://github.com/ClickHouse/ClickHouse/commits/master/tests/testflows/rbac/requirements/requirements.md [Git]: https://git-scm.com/ [MySQL]: https://dev.mysql.com/doc/refman/8.0/en/account-management-statements.html [PostgreSQL]: https://www.postgresql.org/docs/12/user-manag.html diff --git a/utils/github-hook/hook.py b/utils/github-hook/hook.py index 6ec4744c07c..f442fab5279 100644 --- a/utils/github-hook/hook.py +++ b/utils/github-hook/hook.py @@ -7,6 +7,86 @@ import os DB = 'gh-data' RETRIES = 5 +API_URL = 'https://api.github.com/repos/ClickHouse/ClickHouse/' + + +def _reverse_dict_with_list(source): + result = {} + for key, value in source.items(): + for elem in value: + result[elem] = key + return result + + +MARKER_TO_LABEL = { + '- New Feature': ['pr-feature'], + '- Bug Fix': ['pr-bugfix'], + '- Improvement': ['pr-improvement'], + '- Performance Improvement': ['pr-performance'], + '- Backward Incompatible Change': ['pr-backward-incompatible'], + '- Build/Testing/Packaging Improvement': ['pr-build'], + '- Documentation': ['pr-documentation', 'pr-doc-fix'], + '- Other': ['pr-other'], + '- Not for changelog': ['pr-not-for-changelog'] +} + +LABEL_TO_MARKER = _reverse_dict_with_list(MARKER_TO_LABEL) + +DOC_ALERT_LABELS = { + 'pr-feature' +} + + +def set_labels_for_pr(pull_request_number, labels, headers): + data = { + "labels": list(labels) + } + + for i in range(RETRIES): + try: + response = requests.put(API_URL + 'issues/' + str(pull_request_number) + '/labels', json=data, headers=headers) + response.raise_for_status() + break + except Exception as ex: + print("Exception", ex) + time.sleep(0.2) + + +def get_required_labels_from_desc(description, current_labels): + result = set([]) + # find first matching category + for marker, labels in MARKER_TO_LABEL.items(): + if marker in description: + if not any(label in current_labels for label in labels): + result.add(labels[0]) + break + + # if no category than leave as is + if not result: + return current_labels + + # save all old labels except category label + for label in current_labels: + if label not in result and label not in LABEL_TO_MARKER: + result.add(label) + + # if some of labels require doc alert + if any(label in result for label in DOC_ALERT_LABELS): + result.add('doc-alert') + + return result + + +def label_pull_request_event(response): + pull_request = response['pull_request'] + current_labels = set([label['name'] for label in pull_request['labels']]) + pr_description = pull_request['body'] if pull_request['body'] else '' + required_labels = get_required_labels_from_desc(pr_description, current_labels) + if not required_labels.issubset(current_labels): + token = os.getenv('GITHUB_TOKEN') + auth = {'Authorization': 'token ' + token} + set_labels_for_pr(pull_request['number'], required_labels, auth) + def process_issue_event(response): issue = response['issue'] @@ -169,6 +249,7 @@ def event_processor_dispatcher(headers, body, inserter): elif headers['X-Github-Event'] == 'pull_request': result = process_pull_request_event(body) inserter.insert_event_into(DB, 'pull_requests', result) + label_pull_request_event(body) elif headers['X-Github-Event'] == 'pull_request_review': result = process_pull_request_review(body) inserter.insert_event_into(DB, 'pull_requests', result) diff --git a/website/locale/en/LC_MESSAGES/messages.mo b/website/locale/en/LC_MESSAGES/messages.mo index b9f86a35576..370e2c73150 100644 Binary files a/website/locale/en/LC_MESSAGES/messages.mo and b/website/locale/en/LC_MESSAGES/messages.mo differ diff --git a/website/locale/en/LC_MESSAGES/messages.po b/website/locale/en/LC_MESSAGES/messages.po index 99ad4d36573..6b54b96584a 100644 --- a/website/locale/en/LC_MESSAGES/messages.po +++ b/website/locale/en/LC_MESSAGES/messages.po @@ -3,7 +3,6 @@ # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2020. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" @@ -280,12 +279,12 @@ msgstr "Hosting ClickHouse Meetups" msgid "" "ClickHouse meetups are essential for strengthening community worldwide, " "but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " +"Please, fill this form if you want to become one or want to meet " "ClickHouse core team for any other reason." msgstr "" "ClickHouse meetups are essential for strengthening community worldwide, " "but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " +"Please, fill this form if you want to become one or want to meet " "ClickHouse core team for any other reason." #: templates/index/community.html:159 diff --git a/website/locale/es/LC_MESSAGES/messages.mo b/website/locale/es/LC_MESSAGES/messages.mo index 6d3b47d2c1f..888d7a76c4e 100644 Binary files a/website/locale/es/LC_MESSAGES/messages.mo and b/website/locale/es/LC_MESSAGES/messages.mo differ diff --git a/website/locale/es/LC_MESSAGES/messages.po b/website/locale/es/LC_MESSAGES/messages.po index 91f9e158dbc..531a0001c52 100644 --- a/website/locale/es/LC_MESSAGES/messages.po +++ b/website/locale/es/LC_MESSAGES/messages.po @@ -1,389 +1,326 @@ -# Spanish translations for PROJECT. +# Translations template for PROJECT. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2020. +# Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2020-06-17 12:20+0300\n" -"PO-Revision-Date: 2020-03-26 10:19+0300\n" -"Last-Translator: FULL NAME \n" -"Language: es\n" -"Language-Team: es \n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"PO-Revision-Date: 2020-06-17 12:20+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.8.0\n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #: templates/common_meta.html:1 msgid "" -"ClickHouse is a fast open-source column-oriented database management " -"system that allows generating analytical data reports in real-time using " -"SQL queries" +"ClickHouse is a fast open-source column-oriented database management system " +"that allows generating analytical data reports in real-time using SQL queries" msgstr "" -"ClickHouse es un rápido sistema de gestión de bases de datos orientado a " -"columnas de código abierto que permite generar informes de datos " -"analíticos en tiempo real utilizando consultas SQL" #: templates/common_meta.html:6 msgid "ClickHouse - fast open-source OLAP DBMS" -msgstr "ClickHouse - DBMS OLAP de código abierto rápido" +msgstr "" #: templates/common_meta.html:10 msgid "ClickHouse DBMS" -msgstr "Sistema abierto." +msgstr "" #: templates/common_meta.html:32 msgid "open-source" -msgstr "de código abierto" +msgstr "" #: templates/common_meta.html:32 msgid "relational" -msgstr "relacional" +msgstr "" #: templates/common_meta.html:32 msgid "analytics" -msgstr "analítica" +msgstr "" #: templates/common_meta.html:32 msgid "analytical" -msgstr "analítico" +msgstr "" #: templates/common_meta.html:32 msgid "Big Data" -msgstr "Grandes Datos" +msgstr "" #: templates/common_meta.html:32 msgid "web-analytics" -msgstr "Sistema abierto." +msgstr "" #: templates/footer.html:8 msgid "ClickHouse source code is published under the Apache 2.0 License." -msgstr "El código fuente de ClickHouse se publica bajo la licencia Apache 2.0." +msgstr "" #: templates/footer.html:8 msgid "" "Software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR " "CONDITIONS OF ANY KIND, either express or implied." msgstr "" -"El software se distribuye \"TAL CUAL\", SIN GARANTÍAS O CONDICIONES DE " -"NINGÚN TIPO, ya sea expresa o implícita." #: templates/footer.html:11 msgid "Yandex LLC" -msgstr "Sistema abierto." +msgstr "" #: templates/blog/content.html:20 templates/blog/content.html:25 #: templates/blog/content.html:30 msgid "Share on" -msgstr "Compartir en" +msgstr "" #: templates/blog/content.html:37 msgid "Published date" -msgstr "Fecha de publicación" +msgstr "" #: templates/blog/nav.html:20 msgid "New post" -msgstr "Nuevo post" +msgstr "" #: templates/blog/nav.html:25 msgid "Documentation" -msgstr "Documentación" +msgstr "" #: templates/docs/footer.html:3 msgid "Rating" -msgstr "Clasificación" +msgstr "" #: templates/docs/footer.html:3 msgid "votes" -msgstr "voto" +msgstr "" #: templates/docs/footer.html:4 msgid "Article Rating" -msgstr "Clasificación del artículo" +msgstr "" #: templates/docs/footer.html:4 msgid "Was this content helpful?" -msgstr "¿Este contenido fue útil?" +msgstr "" #: templates/docs/footer.html:7 msgid "Unusable" -msgstr "Inutilizable" +msgstr "" #: templates/docs/footer.html:7 msgid "Poor" -msgstr "Pobre" +msgstr "" #: templates/docs/footer.html:7 msgid "Good" -msgstr "Bien" +msgstr "" #: templates/docs/footer.html:7 msgid "Excellent" -msgstr "Excelente" +msgstr "" #: templates/docs/footer.html:8 msgid "documentation" -msgstr "documentación" +msgstr "" #: templates/docs/footer.html:15 msgid "Built from" -msgstr "Construido a partir de" +msgstr "" #: templates/docs/footer.html:15 msgid "published on" -msgstr "publicado en" +msgstr "" #: templates/docs/footer.html:15 msgid "modified on" -msgstr "modificado en" +msgstr "" #: templates/docs/machine-translated.html:3 msgid "Help wanted!" -msgstr "Ayuda quería!" +msgstr "" #: templates/docs/machine-translated.html:4 msgid "" "The following content of this documentation page has been machine-" "translated. But unlike other websites, it is not done on the fly. This " "translated text lives on GitHub repository alongside main ClickHouse " -"codebase and waits for fellow native speakers to make it more human-" -"readable." +"codebase and waits for fellow native speakers to make it more human-readable." msgstr "" -"El siguiente contenido de esta página de documentación ha sido traducido " -"por máquina. Pero a diferencia de otros sitios web, no se hace sobre la " -"marcha. Este texto traducido vive en el repositorio de GitHub junto con " -"la base de código principal de ClickHouse y espera a que otros hablantes " -"nativos lo hagan más legible por humanos." #: templates/docs/machine-translated.html:4 msgid "You can also use the original English version as a reference." -msgstr "También puede usar la versión original en inglés como referencia." +msgstr "" #: templates/docs/machine-translated.html:7 msgid "Help ClickHouse documentation by editing this page" -msgstr "Ayuda a la documentación de ClickHouse editando esta página" +msgstr "" #: templates/docs/sidebar.html:3 msgid "Multi-page or single-page" -msgstr "Multi-página o de una sola página" +msgstr "" #: templates/docs/sidebar.html:5 msgid "Multi-page version" -msgstr "Versión de varias páginas" +msgstr "" #: templates/docs/sidebar.html:8 msgid "Single-page version" -msgstr "Versión de una sola página" +msgstr "" #: templates/docs/sidebar.html:13 msgid "Version" -msgstr "Versión" +msgstr "" #: templates/docs/sidebar.html:13 templates/docs/sidebar.html:19 msgid "latest" -msgstr "reciente" +msgstr "" #: templates/docs/sidebar.html:36 msgid "PDF version" -msgstr "Versión PDF" +msgstr "" #: templates/docs/toc.html:8 msgid "Table of Contents" -msgstr "Tabla de contenido" +msgstr "" #: templates/index/community.html:4 msgid "ClickHouse community" -msgstr "ClickHouse de la comunidad" +msgstr "" #: templates/index/community.html:13 templates/index/community.html:14 msgid "ClickHouse YouTube Channel" -msgstr "ClickHouse Canal de YouTube" +msgstr "" #: templates/index/community.html:25 templates/index/community.html:26 msgid "ClickHouse Official Twitter Account" -msgstr "Cuenta oficial de Twitter de ClickHouse" +msgstr "" #: templates/index/community.html:36 templates/index/community.html:37 msgid "ClickHouse at Telegram" -msgstr "ClickHouse en Telegram" +msgstr "" #: templates/index/community.html:41 msgid "Chat with real users in " -msgstr "Chatear con usuarios reales en " +msgstr "" #: templates/index/community.html:44 templates/index/community.html:116 msgid "English" -msgstr "Ingl" +msgstr "" #: templates/index/community.html:45 msgid "or in" -msgstr "o en" +msgstr "" #: templates/index/community.html:47 templates/index/community.html:117 msgid "Russian" -msgstr "Ruso" +msgstr "" #: templates/index/community.html:65 msgid "Open GitHub issue to ask for help or to file a feature request" msgstr "" -"Abra el problema de GitHub para pedir ayuda o para presentar una " -"solicitud de función" #: templates/index/community.html:76 templates/index/community.html:77 msgid "ClickHouse Slack Workspace" -msgstr "Espacio de trabajo de ClickHouse Slack" +msgstr "" #: templates/index/community.html:82 msgid "Multipurpose public hangout" -msgstr "Lugar de reunión público multiusos" +msgstr "" #: templates/index/community.html:101 msgid "Ask any questions" -msgstr "Haga cualquier pregunta" +msgstr "" #: templates/index/community.html:115 msgid "ClickHouse Blog" msgstr "" -"Bienvenidos al Portal de Licitación Electrónica de Licitación " -"Electrónica" #: templates/index/community.html:116 msgid "in" -msgstr "en" +msgstr "" #: templates/index/community.html:128 templates/index/community.html:129 msgid "ClickHouse at Google Groups" -msgstr "ClickHouse en Grupos de Google" +msgstr "" #: templates/index/community.html:133 msgid "Email discussions" -msgstr "Discusiones por correo electrónico" +msgstr "" #: templates/index/community.html:142 msgid "Like ClickHouse?" -msgstr "¿Te gusta ClickHouse?" +msgstr "" #: templates/index/community.html:143 msgid "Help to spread the word about it via" -msgstr "Ayuda a correr la voz al respecto a través de" +msgstr "" #: templates/index/community.html:144 msgid "and" -msgstr "y" +msgstr "" #: templates/index/community.html:153 msgid "Hosting ClickHouse Meetups" -msgstr "Grupos de Meetup de Hosting ClickHouse" +msgstr "" #: templates/index/community.html:157 msgid "" -"ClickHouse meetups are essential for strengthening community worldwide, " -"but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " -"ClickHouse core team for any other reason." +"ClickHouse meetups are essential for strengthening community worldwide, but " +"they couldn't be possible without the help of local organizers. Please, fill " +"this form if you want to become one or want to meet ClickHouse core team for " +"any other reason." msgstr "" -"Las reuniones de ClickHouse son esenciales para fortalecer la comunidad " -"en todo el mundo, pero no podrían ser posibles sin la ayuda de los " -"organizadores locales. Por favor, sienta este formulario si desea " -"convertirse en uno o quiere conocer al equipo central de ClickHouse por " -"cualquier otra razón." #: templates/index/community.html:159 msgid "ClickHouse Meetup" -msgstr "Haga clic en Meetup de Casa" +msgstr "" #: templates/index/community.html:165 msgid "Name" -msgstr "Nombre" +msgstr "" #: templates/index/community.html:168 msgid "Email" -msgstr "Correo" +msgstr "" #: templates/index/community.html:171 msgid "Company" -msgstr "Empresa" +msgstr "" #: templates/index/community.html:174 msgid "City" -msgstr "Ciudad" +msgstr "" #: templates/index/community.html:179 msgid "We'd like to host a public ClickHouse Meetup" -msgstr "Nos gustaría organizar un Meetup público de ClickHouse" +msgstr "" #: templates/index/community.html:185 msgid "We'd like to invite Yandex ClickHouse team to our office" -msgstr "Nos gustaría invitar al equipo de Yandex ClickHouse a nuestra oficina" +msgstr "" #: templates/index/community.html:191 msgid "We'd like to invite Yandex ClickHouse team to another event we organize" msgstr "" -"Nos gustaría invitar al equipo de Yandex ClickHouse a otro evento que " -"organizamos" #: templates/index/community.html:197 msgid "We're interested in commercial consulting, support or managed service" msgstr "" -"Estamos interesados en consultoría comercial, soporte o servicio " -"gestionado" #: templates/index/community.html:201 msgid "Additional comments" -msgstr "Comentarios adicionales" +msgstr "" #: templates/index/community.html:203 msgid "Send" -msgstr "Enviar" +msgstr "" #: templates/index/community.html:212 msgid "" "If you have any more thoughts or questions, feel free to contact Yandex " "ClickHouse team directly at" msgstr "" -"Si tiene más pensamientos o preguntas, no dude en ponerse en contacto con" -" el equipo de Yandex ClickHouse directamente en" #: templates/index/community.html:213 msgid "turn on JavaScript to see email address" -msgstr "activar JavaScript para ver la dirección de correo electrónico" - -#~ msgid "" -#~ "ClickHouse is an open source column-" -#~ "oriented database management system that " -#~ "allows generating analytical data reports " -#~ "in real time using SQL queries." -#~ msgstr "" -#~ "ClickHouse es un sistema de gestión " -#~ "de bases de datos orientado a " -#~ "columnas de código abierto que permite" -#~ " generar informes de datos analíticos " -#~ "en tiempo real utilizando consultas SQL." - -#~ msgid "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." -#~ msgstr "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." - -#~ msgid "published at" -#~ msgstr "publicado en" - -#~ msgid "modified at" -#~ msgstr "modificado en" - +msgstr "" diff --git a/website/locale/fa/LC_MESSAGES/messages.mo b/website/locale/fa/LC_MESSAGES/messages.mo index 4bb1f2795a4..89c73f3fea4 100644 Binary files a/website/locale/fa/LC_MESSAGES/messages.mo and b/website/locale/fa/LC_MESSAGES/messages.mo differ diff --git a/website/locale/fa/LC_MESSAGES/messages.po b/website/locale/fa/LC_MESSAGES/messages.po index 81fb01be146..565684ac0de 100644 --- a/website/locale/fa/LC_MESSAGES/messages.po +++ b/website/locale/fa/LC_MESSAGES/messages.po @@ -1,381 +1,325 @@ -# Persian translations for PROJECT. +# Translations template for PROJECT. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2020. +# Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2020-06-17 12:20+0300\n" -"PO-Revision-Date: 2020-03-26 10:19+0300\n" -"Last-Translator: FULL NAME \n" -"Language: fa\n" -"Language-Team: fa \n" -"Plural-Forms: nplurals=1; plural=0\n" +"PO-Revision-Date: 2020-06-17 12:20+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.8.0\n" +"Language: fa\n" #: templates/common_meta.html:1 msgid "" -"ClickHouse is a fast open-source column-oriented database management " -"system that allows generating analytical data reports in real-time using " -"SQL queries" +"ClickHouse is a fast open-source column-oriented database management system " +"that allows generating analytical data reports in real-time using SQL queries" msgstr "" -"در تاتر یک منبع باز سیستم مدیریت پایگاه داده ستون گرا سریع است که اجازه " -"می دهد تا تولید گزارش داده تحلیلی در زمان واقعی با استفاده از پرس و جو " -"گذاشتن است" #: templates/common_meta.html:6 msgid "ClickHouse - fast open-source OLAP DBMS" -msgstr "ClickHouse - سریع باز-منبع OLAP DBMS" +msgstr "" #: templates/common_meta.html:10 msgid "ClickHouse DBMS" -msgstr "خانه عروسکی" +msgstr "" #: templates/common_meta.html:32 msgid "open-source" -msgstr "متن باز" +msgstr "" #: templates/common_meta.html:32 msgid "relational" -msgstr "رابطه" +msgstr "" #: templates/common_meta.html:32 msgid "analytics" -msgstr "تجزیه و تحلیل" +msgstr "" #: templates/common_meta.html:32 msgid "analytical" -msgstr "تحلیلی" +msgstr "" #: templates/common_meta.html:32 msgid "Big Data" -msgstr "داده های بزرگ" +msgstr "" #: templates/common_meta.html:32 msgid "web-analytics" -msgstr "تجزیه و تحلیل وب سایت" +msgstr "" #: templates/footer.html:8 msgid "ClickHouse source code is published under the Apache 2.0 License." -msgstr "کد منبع را کلیک کنیدهاوس تحت گواهی 2.0 منتشر شده است." +msgstr "" #: templates/footer.html:8 msgid "" "Software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR " "CONDITIONS OF ANY KIND, either express or implied." msgstr "" -"نرم افزار بر اساس \"به عنوان\" توزیع, بدون ضمانت یا شرایط از هر نوع, هم " -"بیان یا ضمنی." #: templates/footer.html:11 msgid "Yandex LLC" -msgstr "Yandex, LLC" +msgstr "" #: templates/blog/content.html:20 templates/blog/content.html:25 #: templates/blog/content.html:30 msgid "Share on" -msgstr "اشتراک در" +msgstr "" #: templates/blog/content.html:37 msgid "Published date" -msgstr "تاریخ انتشار" +msgstr "" #: templates/blog/nav.html:20 msgid "New post" -msgstr "جدید & nbsp;پست" +msgstr "" #: templates/blog/nav.html:25 msgid "Documentation" -msgstr "مستندات" +msgstr "" #: templates/docs/footer.html:3 msgid "Rating" -msgstr "درجهبندی" +msgstr "" #: templates/docs/footer.html:3 msgid "votes" -msgstr "رای" +msgstr "" #: templates/docs/footer.html:4 msgid "Article Rating" -msgstr "رتبه مقاله" +msgstr "" #: templates/docs/footer.html:4 msgid "Was this content helpful?" -msgstr "این مطالب مفید بود?" +msgstr "" #: templates/docs/footer.html:7 msgid "Unusable" -msgstr "غیرقابل استفاده" +msgstr "" #: templates/docs/footer.html:7 msgid "Poor" -msgstr "فقیر" +msgstr "" #: templates/docs/footer.html:7 msgid "Good" -msgstr "خوبه" +msgstr "" #: templates/docs/footer.html:7 msgid "Excellent" -msgstr "عالیه" +msgstr "" #: templates/docs/footer.html:8 msgid "documentation" -msgstr "مستندات" +msgstr "" #: templates/docs/footer.html:15 msgid "Built from" -msgstr "ساخته شده از" +msgstr "" #: templates/docs/footer.html:15 msgid "published on" -msgstr "منتشر شده در" +msgstr "" #: templates/docs/footer.html:15 msgid "modified on" -msgstr "تغییریافته" +msgstr "" #: templates/docs/machine-translated.html:3 msgid "Help wanted!" -msgstr "راهنما می خواستم!" +msgstr "" #: templates/docs/machine-translated.html:4 msgid "" "The following content of this documentation page has been machine-" "translated. But unlike other websites, it is not done on the fly. This " "translated text lives on GitHub repository alongside main ClickHouse " -"codebase and waits for fellow native speakers to make it more human-" -"readable." +"codebase and waits for fellow native speakers to make it more human-readable." msgstr "" -"محتوای زیر از این صفحه اسناد شده است ماشین ترجمه. اما بر خلاف وب سایت های" -" دیگر, این است که در پرواز انجام نمی. این متن ترجمه شده در مخزن گیتهاب در" -" کنار پایگاه داده اصلی خانه کلیک زندگی می کند و منتظر سخنرانان مادری " -"همکار به انسان بیشتر قابل خواندن است." #: templates/docs/machine-translated.html:4 msgid "You can also use the original English version as a reference." -msgstr "شما همچنین می توانید نسخه اصلی انگلیسی به عنوان یک مرجع استفاده کنید." +msgstr "" #: templates/docs/machine-translated.html:7 msgid "Help ClickHouse documentation by editing this page" -msgstr "راهنما مستندات تاتر با ویرایش این صفحه" +msgstr "" #: templates/docs/sidebar.html:3 msgid "Multi-page or single-page" -msgstr "چند صفحه یا یک صفحه" +msgstr "" #: templates/docs/sidebar.html:5 msgid "Multi-page version" -msgstr "نسخه چند صفحه ای" +msgstr "" #: templates/docs/sidebar.html:8 msgid "Single-page version" -msgstr "نسخه تک صفحه ای" +msgstr "" #: templates/docs/sidebar.html:13 msgid "Version" -msgstr "نسخه" +msgstr "" #: templates/docs/sidebar.html:13 templates/docs/sidebar.html:19 msgid "latest" -msgstr "جدیدترین" +msgstr "" #: templates/docs/sidebar.html:36 msgid "PDF version" -msgstr "نسخه PDF" +msgstr "" #: templates/docs/toc.html:8 msgid "Table of Contents" -msgstr "جدول محتویات" +msgstr "" #: templates/index/community.html:4 msgid "ClickHouse community" -msgstr "جامعه کلیک" +msgstr "" #: templates/index/community.html:13 templates/index/community.html:14 msgid "ClickHouse YouTube Channel" -msgstr "تاتر کانال یوتیوب" +msgstr "" #: templates/index/community.html:25 templates/index/community.html:26 msgid "ClickHouse Official Twitter Account" -msgstr "حساب توییتر رسمی کلیک کنید" +msgstr "" #: templates/index/community.html:36 templates/index/community.html:37 msgid "ClickHouse at Telegram" -msgstr "تاتر در تلگرام" +msgstr "" #: templates/index/community.html:41 msgid "Chat with real users in " -msgstr "چت با کاربران واقعی در " +msgstr "" #: templates/index/community.html:44 templates/index/community.html:116 msgid "English" -msgstr "انگلیسی" +msgstr "" #: templates/index/community.html:45 msgid "or in" -msgstr "یا در" +msgstr "" #: templates/index/community.html:47 templates/index/community.html:117 msgid "Russian" -msgstr "روسی" +msgstr "" #: templates/index/community.html:65 msgid "Open GitHub issue to ask for help or to file a feature request" -msgstr "باز کردن مشکل گیتهاب برای درخواست کمک و یا به فایل درخواست ویژگی" +msgstr "" #: templates/index/community.html:76 templates/index/community.html:77 msgid "ClickHouse Slack Workspace" -msgstr "فضای کاری شل کلیک" +msgstr "" #: templates/index/community.html:82 msgid "Multipurpose public hangout" -msgstr "چند منظوره پاتوق عمومی" +msgstr "" #: templates/index/community.html:101 msgid "Ask any questions" -msgstr "هر گونه سوال بپرسید" +msgstr "" #: templates/index/community.html:115 msgid "ClickHouse Blog" -msgstr "وبلاگ کلیک" +msgstr "" #: templates/index/community.html:116 msgid "in" -msgstr "داخل" +msgstr "" #: templates/index/community.html:128 templates/index/community.html:129 msgid "ClickHouse at Google Groups" -msgstr "تاتر در گروه های گوگل" +msgstr "" #: templates/index/community.html:133 msgid "Email discussions" -msgstr "بحث های ایمیل" +msgstr "" #: templates/index/community.html:142 msgid "Like ClickHouse?" -msgstr "مانند خانه کلیک?" +msgstr "" #: templates/index/community.html:143 msgid "Help to spread the word about it via" -msgstr "کمک به گسترش این کلمه از طریق" +msgstr "" #: templates/index/community.html:144 msgid "and" -msgstr "و" +msgstr "" #: templates/index/community.html:153 msgid "Hosting ClickHouse Meetups" -msgstr "میزبانی اکسسوری تاتر" +msgstr "" #: templates/index/community.html:157 msgid "" -"ClickHouse meetups are essential for strengthening community worldwide, " -"but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " -"ClickHouse core team for any other reason." +"ClickHouse meetups are essential for strengthening community worldwide, but " +"they couldn't be possible without the help of local organizers. Please, fill " +"this form if you want to become one or want to meet ClickHouse core team for " +"any other reason." msgstr "" -"اکسسوری کلیک برای تقویت جامعه در سراسر جهان ضروری است, اما نمی تواند بدون" -" کمک سازمان دهندگان محلی امکان پذیر است. لطفا, احساس این فرم اگر شما می " -"خواهید برای تبدیل شدن به یک و یا می خواهید برای دیدار با تیم هسته کلیکاوس" -" به هر دلیلی دیگر." #: templates/index/community.html:159 msgid "ClickHouse Meetup" -msgstr "ناهار خانه" +msgstr "" #: templates/index/community.html:165 msgid "Name" -msgstr "نام" +msgstr "" #: templates/index/community.html:168 msgid "Email" -msgstr "رایانامه" +msgstr "" #: templates/index/community.html:171 msgid "Company" -msgstr "شرکت" +msgstr "" #: templates/index/community.html:174 msgid "City" -msgstr "شهر" +msgstr "" #: templates/index/community.html:179 msgid "We'd like to host a public ClickHouse Meetup" -msgstr "ما می خواهیم میزبان یک ناهار عمومی باشیم" +msgstr "" #: templates/index/community.html:185 msgid "We'd like to invite Yandex ClickHouse team to our office" -msgstr "ما می خواهیم از تیم یاندکس کلیک هاوس به دفتر ما دعوت کنیم" +msgstr "" #: templates/index/community.html:191 msgid "We'd like to invite Yandex ClickHouse team to another event we organize" msgstr "" -"ما می خواهیم از تیم یاندکس کلیک هاوس به رویداد دیگری که سازماندهی می کنیم" -" دعوت کنیم" #: templates/index/community.html:197 msgid "We're interested in commercial consulting, support or managed service" -msgstr "ما علاقه مند به مشاوره تجاری هستید, پشتیبانی و یا خدمات مدیریت" +msgstr "" #: templates/index/community.html:201 msgid "Additional comments" -msgstr "نظرات اضافی" +msgstr "" #: templates/index/community.html:203 msgid "Send" -msgstr "ارسال" +msgstr "" #: templates/index/community.html:212 msgid "" "If you have any more thoughts or questions, feel free to contact Yandex " "ClickHouse team directly at" msgstr "" -"اگر شما هر گونه افکار و یا سوالات بیشتر, احساس رایگان برای تماس با یاندکس" -" کلیک تیم به طور مستقیم در" #: templates/index/community.html:213 msgid "turn on JavaScript to see email address" -msgstr "روشن کردن جاوا اسکریپت برای دیدن نشانی رایانامه" - -#~ msgid "" -#~ "ClickHouse is an open source column-" -#~ "oriented database management system that " -#~ "allows generating analytical data reports " -#~ "in real time using SQL queries." -#~ msgstr "" -#~ "در تاتر یک منبع ستون گرا سیستم " -#~ "مدیریت پایگاه داده باز است که " -#~ "اجازه می دهد تا تولید گزارش داده" -#~ " تحلیلی در زمان واقعی با استفاده " -#~ "از پرس و جو گذاشتن است." - -#~ msgid "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." -#~ msgstr "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." - -#~ msgid "published at" -#~ msgstr "منتشر شده در" - -#~ msgid "modified at" -#~ msgstr "تغییریافته در" - +msgstr "" diff --git a/website/locale/fr/LC_MESSAGES/messages.mo b/website/locale/fr/LC_MESSAGES/messages.mo index f32b4a32da2..43fcad3bd73 100644 Binary files a/website/locale/fr/LC_MESSAGES/messages.mo and b/website/locale/fr/LC_MESSAGES/messages.mo differ diff --git a/website/locale/fr/LC_MESSAGES/messages.po b/website/locale/fr/LC_MESSAGES/messages.po index 76839376c85..5ccc7c3c87d 100644 --- a/website/locale/fr/LC_MESSAGES/messages.po +++ b/website/locale/fr/LC_MESSAGES/messages.po @@ -1,390 +1,326 @@ -# French translations for PROJECT. +# Translations template for PROJECT. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2020. +# Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2020-06-17 12:20+0300\n" -"PO-Revision-Date: 2020-03-30 15:12+0300\n" -"Last-Translator: FULL NAME \n" -"Language: fr\n" -"Language-Team: fr \n" -"Plural-Forms: nplurals=2; plural=(n > 1)\n" +"PO-Revision-Date: 2020-06-17 12:20+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.8.0\n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" #: templates/common_meta.html:1 msgid "" -"ClickHouse is a fast open-source column-oriented database management " -"system that allows generating analytical data reports in real-time using " -"SQL queries" +"ClickHouse is a fast open-source column-oriented database management system " +"that allows generating analytical data reports in real-time using SQL queries" msgstr "" -"ClickHouse est un système de gestion de base de données orienté colonne " -"open-source rapide qui permet de générer des rapports de données " -"analytiques en temps réel à l'aide de requêtes SQL" #: templates/common_meta.html:6 msgid "ClickHouse - fast open-source OLAP DBMS" -msgstr "ClickHouse-SGBD OLAP open-source rapide" +msgstr "" #: templates/common_meta.html:10 msgid "ClickHouse DBMS" -msgstr "SGBD ClickHouse" +msgstr "" #: templates/common_meta.html:32 msgid "open-source" -msgstr "open-source" +msgstr "" #: templates/common_meta.html:32 msgid "relational" -msgstr "relationnel" +msgstr "" #: templates/common_meta.html:32 msgid "analytics" -msgstr "Analytics" +msgstr "" #: templates/common_meta.html:32 msgid "analytical" -msgstr "analytique" +msgstr "" #: templates/common_meta.html:32 msgid "Big Data" -msgstr "Big Data" +msgstr "" #: templates/common_meta.html:32 msgid "web-analytics" -msgstr "web-analytics" +msgstr "" #: templates/footer.html:8 msgid "ClickHouse source code is published under the Apache 2.0 License." -msgstr "Le code source de ClickHouse est publié sous la licence Apache 2.0." +msgstr "" #: templates/footer.html:8 msgid "" "Software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR " "CONDITIONS OF ANY KIND, either express or implied." msgstr "" -"Le logiciel est distribué \"tel quel\", sans garantie ni condition " -"d'AUCUNE SORTE, expresse ou implicite." #: templates/footer.html:11 msgid "Yandex LLC" -msgstr "Yandex LLC" +msgstr "" #: templates/blog/content.html:20 templates/blog/content.html:25 #: templates/blog/content.html:30 msgid "Share on" -msgstr "Partager sur" +msgstr "" #: templates/blog/content.html:37 msgid "Published date" -msgstr "Date de publication" +msgstr "" #: templates/blog/nav.html:20 msgid "New post" -msgstr "Nouvelles post" +msgstr "" #: templates/blog/nav.html:25 msgid "Documentation" -msgstr "Documentation" +msgstr "" #: templates/docs/footer.html:3 msgid "Rating" -msgstr "Évaluation" +msgstr "" #: templates/docs/footer.html:3 msgid "votes" -msgstr "vote" +msgstr "" #: templates/docs/footer.html:4 msgid "Article Rating" -msgstr "L'Article De Notation" +msgstr "" #: templates/docs/footer.html:4 msgid "Was this content helpful?" -msgstr "Ce contenu a été utile?" +msgstr "" #: templates/docs/footer.html:7 msgid "Unusable" -msgstr "Inutilisable" +msgstr "" #: templates/docs/footer.html:7 msgid "Poor" -msgstr "Pauvre" +msgstr "" #: templates/docs/footer.html:7 msgid "Good" -msgstr "Bien" +msgstr "" #: templates/docs/footer.html:7 msgid "Excellent" -msgstr "Excellent" +msgstr "" #: templates/docs/footer.html:8 msgid "documentation" -msgstr "documentation" +msgstr "" #: templates/docs/footer.html:15 msgid "Built from" -msgstr "Construit à partir de" +msgstr "" #: templates/docs/footer.html:15 msgid "published on" -msgstr "publié le" +msgstr "" #: templates/docs/footer.html:15 msgid "modified on" -msgstr "modifié sur" +msgstr "" #: templates/docs/machine-translated.html:3 msgid "Help wanted!" -msgstr "Demander de l'aide!" +msgstr "" #: templates/docs/machine-translated.html:4 msgid "" "The following content of this documentation page has been machine-" "translated. But unlike other websites, it is not done on the fly. This " "translated text lives on GitHub repository alongside main ClickHouse " -"codebase and waits for fellow native speakers to make it more human-" -"readable." +"codebase and waits for fellow native speakers to make it more human-readable." msgstr "" -"Le contenu suivant de cette page de documentation a été traduit à la " -"machine. Mais contrairement à d'autres sites web, il ne se fait pas à la " -"volée. Ce texte traduit vit sur le dépôt GitHub aux côtés de la base de " -"code ClickHouse principale et attend que d'autres locuteurs natifs le " -"rendent plus lisible par l'homme." #: templates/docs/machine-translated.html:4 msgid "You can also use the original English version as a reference." msgstr "" -"Vous pouvez également utiliser la version originale anglaise comme " -"référence." #: templates/docs/machine-translated.html:7 msgid "Help ClickHouse documentation by editing this page" -msgstr "Aide clickhouse documentation en éditant cette page" +msgstr "" #: templates/docs/sidebar.html:3 msgid "Multi-page or single-page" -msgstr "Multi-page ou une seule page" +msgstr "" #: templates/docs/sidebar.html:5 msgid "Multi-page version" -msgstr "Multi-version de la page" +msgstr "" #: templates/docs/sidebar.html:8 msgid "Single-page version" -msgstr "Version d'une seule page" +msgstr "" #: templates/docs/sidebar.html:13 msgid "Version" -msgstr "Version" +msgstr "" #: templates/docs/sidebar.html:13 templates/docs/sidebar.html:19 msgid "latest" -msgstr "dernier" +msgstr "" #: templates/docs/sidebar.html:36 msgid "PDF version" -msgstr "Version PDF" +msgstr "" #: templates/docs/toc.html:8 msgid "Table of Contents" -msgstr "Table des matières" +msgstr "" #: templates/index/community.html:4 msgid "ClickHouse community" -msgstr "Clickhouse communauté" +msgstr "" #: templates/index/community.html:13 templates/index/community.html:14 msgid "ClickHouse YouTube Channel" -msgstr "ClickHouse Chaîne YouTube" +msgstr "" #: templates/index/community.html:25 templates/index/community.html:26 msgid "ClickHouse Official Twitter Account" -msgstr "ClickHouse Compte Twitter Officiel" +msgstr "" #: templates/index/community.html:36 templates/index/community.html:37 msgid "ClickHouse at Telegram" -msgstr "ClickHouse au Télégramme" +msgstr "" #: templates/index/community.html:41 msgid "Chat with real users in " -msgstr "Discuter avec de vrais utilisateurs dans " +msgstr "" #: templates/index/community.html:44 templates/index/community.html:116 msgid "English" -msgstr "Anglais" +msgstr "" #: templates/index/community.html:45 msgid "or in" -msgstr "ou dans" +msgstr "" #: templates/index/community.html:47 templates/index/community.html:117 msgid "Russian" -msgstr "Russe" +msgstr "" #: templates/index/community.html:65 msgid "Open GitHub issue to ask for help or to file a feature request" msgstr "" -"Ouvrir GitHub question de demander de l'aide, ou pour déposer une demande" -" de fonctionnalité" #: templates/index/community.html:76 templates/index/community.html:77 msgid "ClickHouse Slack Workspace" -msgstr "Espace De Travail ClickHouse Slack" +msgstr "" #: templates/index/community.html:82 msgid "Multipurpose public hangout" -msgstr "Lieu de rencontre public polyvalent" +msgstr "" #: templates/index/community.html:101 msgid "Ask any questions" -msgstr "Posez toutes les questions" +msgstr "" #: templates/index/community.html:115 msgid "ClickHouse Blog" -msgstr "Clickhouse Blog" +msgstr "" #: templates/index/community.html:116 msgid "in" -msgstr "dans" +msgstr "" #: templates/index/community.html:128 templates/index/community.html:129 msgid "ClickHouse at Google Groups" -msgstr "ClickHouse à Google Groupes" +msgstr "" #: templates/index/community.html:133 msgid "Email discussions" -msgstr "Discussions par courriel" +msgstr "" #: templates/index/community.html:142 msgid "Like ClickHouse?" -msgstr "Comme ClickHouse?" +msgstr "" #: templates/index/community.html:143 msgid "Help to spread the word about it via" -msgstr "Aider à passer le mot à ce sujet via" +msgstr "" #: templates/index/community.html:144 msgid "and" -msgstr "et" +msgstr "" #: templates/index/community.html:153 msgid "Hosting ClickHouse Meetups" -msgstr "Accueil Clickhouse Meetups" +msgstr "" #: templates/index/community.html:157 msgid "" -"ClickHouse meetups are essential for strengthening community worldwide, " -"but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " -"ClickHouse core team for any other reason." +"ClickHouse meetups are essential for strengthening community worldwide, but " +"they couldn't be possible without the help of local organizers. Please, fill " +"this form if you want to become one or want to meet ClickHouse core team for " +"any other reason." msgstr "" -"Les rencontres ClickHouse sont essentielles pour renforcer la communauté " -"dans le monde entier, mais elles ne pourraient pas être possibles sans " -"l'aide d'organisateurs locaux. S'il vous plaît, sentez ce formulaire si " -"vous voulez devenir l'une ou souhaitez rencontrer ClickHouse équipe de " -"base pour toute autre raison." #: templates/index/community.html:159 msgid "ClickHouse Meetup" -msgstr "Clickhouse Meetup" +msgstr "" #: templates/index/community.html:165 msgid "Name" -msgstr "Nom" +msgstr "" #: templates/index/community.html:168 msgid "Email" -msgstr "Courriel" +msgstr "" #: templates/index/community.html:171 msgid "Company" -msgstr "Entreprise" +msgstr "" #: templates/index/community.html:174 msgid "City" -msgstr "Ville" +msgstr "" #: templates/index/community.html:179 msgid "We'd like to host a public ClickHouse Meetup" -msgstr "Nous aimerions organiser un Meetup public ClickHouse" +msgstr "" #: templates/index/community.html:185 msgid "We'd like to invite Yandex ClickHouse team to our office" -msgstr "Nous aimerions inviter l'équipe de Yandex ClickHouse à notre bureau" +msgstr "" #: templates/index/community.html:191 msgid "We'd like to invite Yandex ClickHouse team to another event we organize" msgstr "" -"Nous aimerions inviter l'équipe de Yandex ClickHouse à un autre événement" -" que nous organisons" #: templates/index/community.html:197 msgid "We're interested in commercial consulting, support or managed service" msgstr "" -"Nous sommes intéressés par le conseil commercial, le soutien ou le " -"service géré" #: templates/index/community.html:201 msgid "Additional comments" -msgstr "Commentaires supplémentaires" +msgstr "" #: templates/index/community.html:203 msgid "Send" -msgstr "Envoyer" +msgstr "" #: templates/index/community.html:212 msgid "" "If you have any more thoughts or questions, feel free to contact Yandex " "ClickHouse team directly at" msgstr "" -"Si vous avez d'autres pensées ou questions, n'hésitez pas à contacter " -"L'équipe Yandex ClickHouse directement à" #: templates/index/community.html:213 msgid "turn on JavaScript to see email address" -msgstr "activer JavaScript pour voir l'adresse e-mail" - -#~ msgid "" -#~ "ClickHouse is an open source column-" -#~ "oriented database management system that " -#~ "allows generating analytical data reports " -#~ "in real time using SQL queries." -#~ msgstr "" -#~ "ClickHouse est un système de gestion " -#~ "de base de données orienté colonne " -#~ "open source qui permet de générer " -#~ "des rapports de données analytiques en" -#~ " temps réel à l'aide de requêtes " -#~ "SQL." - -#~ msgid "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." -#~ msgstr "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." - -#~ msgid "published at" -#~ msgstr "publié à" - -#~ msgid "modified at" -#~ msgstr "modifié à" - +msgstr "" diff --git a/website/locale/ja/LC_MESSAGES/messages.mo b/website/locale/ja/LC_MESSAGES/messages.mo index a4634437aeb..2061fefa110 100644 Binary files a/website/locale/ja/LC_MESSAGES/messages.mo and b/website/locale/ja/LC_MESSAGES/messages.mo differ diff --git a/website/locale/ja/LC_MESSAGES/messages.po b/website/locale/ja/LC_MESSAGES/messages.po index 37d346b446b..1e803f62dc6 100644 --- a/website/locale/ja/LC_MESSAGES/messages.po +++ b/website/locale/ja/LC_MESSAGES/messages.po @@ -1,363 +1,326 @@ -# Japanese translations for PROJECT. +# Translations template for PROJECT. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2020. +# Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2020-06-17 12:20+0300\n" -"PO-Revision-Date: 2020-03-26 10:19+0300\n" -"Last-Translator: FULL NAME \n" -"Language: ja\n" -"Language-Team: ja \n" -"Plural-Forms: nplurals=1; plural=0\n" +"PO-Revision-Date: 2020-06-17 12:20+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.8.0\n" +"Language: ja\n" +"Plural-Forms: nplurals=1; plural=0;\n" #: templates/common_meta.html:1 msgid "" -"ClickHouse is a fast open-source column-oriented database management " -"system that allows generating analytical data reports in real-time using " -"SQL queries" -msgstr "ClickHouseがオープンソース列指向データベース管理システムで生成解析データ報告をリアルタイムのSQLクエリー" +"ClickHouse is a fast open-source column-oriented database management system " +"that allows generating analytical data reports in real-time using SQL queries" +msgstr "" #: templates/common_meta.html:6 msgid "ClickHouse - fast open-source OLAP DBMS" -msgstr "ツ環板篠ョツ嘉ッツ偲青エツδツ-ツエツスツ-ツシツ" +msgstr "" #: templates/common_meta.html:10 msgid "ClickHouse DBMS" -msgstr "クリックハウスDBMS" +msgstr "" #: templates/common_meta.html:32 msgid "open-source" -msgstr "オープンソース" +msgstr "" #: templates/common_meta.html:32 msgid "relational" -msgstr "関係" +msgstr "" #: templates/common_meta.html:32 msgid "analytics" -msgstr "analytics" +msgstr "" #: templates/common_meta.html:32 msgid "analytical" -msgstr "分析" +msgstr "" #: templates/common_meta.html:32 msgid "Big Data" -msgstr "ビッグデータ" +msgstr "" #: templates/common_meta.html:32 msgid "web-analytics" -msgstr "ウェブ分析" +msgstr "" #: templates/footer.html:8 msgid "ClickHouse source code is published under the Apache 2.0 License." -msgstr "ClickHouseソースコードが公開されてApache2.0のライセンスです。" +msgstr "" #: templates/footer.html:8 msgid "" "Software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR " "CONDITIONS OF ANY KIND, either express or implied." -msgstr "ソフトウェアは、明示または黙示を問わず、いかなる種類の保証または条件なしに、\"現状のまま\"ベースで配布されます。" +msgstr "" #: templates/footer.html:11 msgid "Yandex LLC" -msgstr "Yandex LLC" +msgstr "" #: templates/blog/content.html:20 templates/blog/content.html:25 #: templates/blog/content.html:30 msgid "Share on" -msgstr "共有" +msgstr "" #: templates/blog/content.html:37 msgid "Published date" -msgstr "公開日" +msgstr "" #: templates/blog/nav.html:20 msgid "New post" -msgstr "新しい ポスト" +msgstr "" #: templates/blog/nav.html:25 msgid "Documentation" -msgstr "文書" +msgstr "" #: templates/docs/footer.html:3 msgid "Rating" -msgstr "評価" +msgstr "" #: templates/docs/footer.html:3 msgid "votes" -msgstr "投票" +msgstr "" #: templates/docs/footer.html:4 msgid "Article Rating" -msgstr "記事の評価" +msgstr "" #: templates/docs/footer.html:4 msgid "Was this content helpful?" -msgstr "この内容は有用だったか。" +msgstr "" #: templates/docs/footer.html:7 msgid "Unusable" -msgstr "使用不可" +msgstr "" #: templates/docs/footer.html:7 msgid "Poor" -msgstr "貧しい" +msgstr "" #: templates/docs/footer.html:7 msgid "Good" -msgstr "よし" +msgstr "" #: templates/docs/footer.html:7 msgid "Excellent" -msgstr "優れた" +msgstr "" #: templates/docs/footer.html:8 msgid "documentation" -msgstr "文書" +msgstr "" #: templates/docs/footer.html:15 msgid "Built from" -msgstr "から構築" +msgstr "" #: templates/docs/footer.html:15 msgid "published on" -msgstr "掲載され" +msgstr "" #: templates/docs/footer.html:15 msgid "modified on" -msgstr "に変更" +msgstr "" #: templates/docs/machine-translated.html:3 msgid "Help wanted!" -msgstr "助けが欲しかった!" +msgstr "" #: templates/docs/machine-translated.html:4 msgid "" "The following content of this documentation page has been machine-" "translated. But unlike other websites, it is not done on the fly. This " "translated text lives on GitHub repository alongside main ClickHouse " -"codebase and waits for fellow native speakers to make it more human-" -"readable." +"codebase and waits for fellow native speakers to make it more human-readable." msgstr "" -"このドキュメントページの以下の内容は機械翻訳されています。 異な他のウェブサイトで行われませんができます。 " -"この翻訳テキスト生活をGitHubリポジトリとClickHouseコードベース、待ち員ネイティブスピーカーで人間が読む." #: templates/docs/machine-translated.html:4 msgid "You can also use the original English version as a reference." -msgstr "また、参照として、元の英語版を使用することができます。" +msgstr "" #: templates/docs/machine-translated.html:7 msgid "Help ClickHouse documentation by editing this page" -msgstr "このページを編集してClickHouseの文書を編集する" +msgstr "" #: templates/docs/sidebar.html:3 msgid "Multi-page or single-page" -msgstr "複数ページまたは単一ページ" +msgstr "" #: templates/docs/sidebar.html:5 msgid "Multi-page version" -msgstr "複数ページバージョン" +msgstr "" #: templates/docs/sidebar.html:8 msgid "Single-page version" -msgstr "単一ページ版" +msgstr "" #: templates/docs/sidebar.html:13 msgid "Version" -msgstr "バージョン" +msgstr "" #: templates/docs/sidebar.html:13 templates/docs/sidebar.html:19 msgid "latest" -msgstr "最新の" +msgstr "" #: templates/docs/sidebar.html:36 msgid "PDF version" -msgstr "PDFバージョン" +msgstr "" #: templates/docs/toc.html:8 msgid "Table of Contents" -msgstr "テーブルの内容" +msgstr "" #: templates/index/community.html:4 msgid "ClickHouse community" -msgstr "ClickHouse地域" +msgstr "" #: templates/index/community.html:13 templates/index/community.html:14 msgid "ClickHouse YouTube Channel" -msgstr "ClickHouse YouTubeチャンネル" +msgstr "" #: templates/index/community.html:25 templates/index/community.html:26 msgid "ClickHouse Official Twitter Account" -msgstr "ClickHouse公式Twitterアカウント" +msgstr "" #: templates/index/community.html:36 templates/index/community.html:37 msgid "ClickHouse at Telegram" -msgstr "ClickHouseで電報" +msgstr "" #: templates/index/community.html:41 msgid "Chat with real users in " -msgstr "で実際のユーザーとチャット " +msgstr "" #: templates/index/community.html:44 templates/index/community.html:116 msgid "English" -msgstr "英語" +msgstr "" #: templates/index/community.html:45 msgid "or in" -msgstr "または" +msgstr "" #: templates/index/community.html:47 templates/index/community.html:117 msgid "Russian" -msgstr "ロシア語" +msgstr "" #: templates/index/community.html:65 msgid "Open GitHub issue to ask for help or to file a feature request" -msgstr "GitHub issueを開いて助けを求めたり、機能要求を提出したりする" +msgstr "" #: templates/index/community.html:76 templates/index/community.html:77 msgid "ClickHouse Slack Workspace" -msgstr "ClickHouseみワークスペース" +msgstr "" #: templates/index/community.html:82 msgid "Multipurpose public hangout" -msgstr "多目的パブリックハングアウト" +msgstr "" #: templates/index/community.html:101 msgid "Ask any questions" -msgstr "質問をする" +msgstr "" #: templates/index/community.html:115 msgid "ClickHouse Blog" -msgstr "ClickHouseブログ" +msgstr "" #: templates/index/community.html:116 msgid "in" -msgstr "で" +msgstr "" #: templates/index/community.html:128 templates/index/community.html:129 msgid "ClickHouse at Google Groups" -msgstr "Googleグループのクリックハウス" +msgstr "" #: templates/index/community.html:133 msgid "Email discussions" -msgstr "メールでの議論" +msgstr "" #: templates/index/community.html:142 msgid "Like ClickHouse?" -msgstr "ClickHouseのような?" +msgstr "" #: templates/index/community.html:143 msgid "Help to spread the word about it via" -msgstr "それについての言葉を広めるのに役立ちます" +msgstr "" #: templates/index/community.html:144 msgid "and" -msgstr "と" +msgstr "" #: templates/index/community.html:153 msgid "Hosting ClickHouse Meetups" -msgstr "開催ClickHouse Meetups" +msgstr "" #: templates/index/community.html:157 msgid "" -"ClickHouse meetups are essential for strengthening community worldwide, " -"but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " -"ClickHouse core team for any other reason." +"ClickHouse meetups are essential for strengthening community worldwide, but " +"they couldn't be possible without the help of local organizers. Please, fill " +"this form if you want to become one or want to meet ClickHouse core team for " +"any other reason." msgstr "" -"ClickHouseの交流会は、世界中のコミュニティを強化するために不可欠ですが、彼らは地元の主催者の助けなしには不可能でした。 " -"ツつィツ姪\"ツつ\"ツ債ツづュツつケツづ債、ツつィツ電ツ話ツづツつィツ甘ィツつ\"ツ致ツつオツづ慊つキツ。" #: templates/index/community.html:159 msgid "ClickHouse Meetup" -msgstr "クリックハウスミート" +msgstr "" #: templates/index/community.html:165 msgid "Name" -msgstr "名前" +msgstr "" #: templates/index/community.html:168 msgid "Email" -msgstr "メール" +msgstr "" #: templates/index/community.html:171 msgid "Company" -msgstr "会社" +msgstr "" #: templates/index/community.html:174 msgid "City" -msgstr "市" +msgstr "" #: templates/index/community.html:179 msgid "We'd like to host a public ClickHouse Meetup" -msgstr "というホストの公ClickHouseスク管理のツールとして利用" +msgstr "" #: templates/index/community.html:185 msgid "We'd like to invite Yandex ClickHouse team to our office" -msgstr "という招待Yandex ClickHouseチーム事務局" +msgstr "" #: templates/index/community.html:191 msgid "We'd like to invite Yandex ClickHouse team to another event we organize" -msgstr "私たちは、整理別のイベントにYandexのClickHouseチームを招待したいと思います" +msgstr "" #: templates/index/community.html:197 msgid "We're interested in commercial consulting, support or managed service" -msgstr "しい商業コンサルティングや管理サービス" +msgstr "" #: templates/index/community.html:201 msgid "Additional comments" -msgstr "追加コメント" +msgstr "" #: templates/index/community.html:203 msgid "Send" -msgstr "送信" +msgstr "" #: templates/index/community.html:212 msgid "" "If you have any more thoughts or questions, feel free to contact Yandex " "ClickHouse team directly at" -msgstr "これ以上の考えや質問がある場合は、Yandex ClickHouseチームに直接お気軽にお問い合わせください" +msgstr "" #: templates/index/community.html:213 msgid "turn on JavaScript to see email address" -msgstr "turn on JavaScriptを見るメールアドレス" - -#~ msgid "" -#~ "ClickHouse is an open source column-" -#~ "oriented database management system that " -#~ "allows generating analytical data reports " -#~ "in real time using SQL queries." -#~ msgstr "ClickHouseオープンソース列指向データベース管理システムで生成解析データをリアルタイムのレポート用のSQLクエリ." - -#~ msgid "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." -#~ msgstr "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." - -#~ msgid "published at" -#~ msgstr "で公開" - -#~ msgid "modified at" -#~ msgstr "で変更" - +msgstr "" diff --git a/website/locale/messages.pot b/website/locale/messages.pot index be81e88e5a7..65d62f8bebb 100644 --- a/website/locale/messages.pot +++ b/website/locale/messages.pot @@ -268,7 +268,7 @@ msgstr "" msgid "" "ClickHouse meetups are essential for strengthening community worldwide, " "but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " +"Please, fill this form if you want to become one or want to meet " "ClickHouse core team for any other reason." msgstr "" diff --git a/website/locale/ru/LC_MESSAGES/messages.mo b/website/locale/ru/LC_MESSAGES/messages.mo index e6760771d66..0ed39012330 100644 Binary files a/website/locale/ru/LC_MESSAGES/messages.mo and b/website/locale/ru/LC_MESSAGES/messages.mo differ diff --git a/website/locale/ru/LC_MESSAGES/messages.po b/website/locale/ru/LC_MESSAGES/messages.po index 41be4dca676..8760024a107 100644 --- a/website/locale/ru/LC_MESSAGES/messages.po +++ b/website/locale/ru/LC_MESSAGES/messages.po @@ -1,408 +1,327 @@ -# Russian translations for PROJECT. +# Translations template for PROJECT. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2020. +# Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2020-06-17 12:20+0300\n" -"PO-Revision-Date: 2020-03-26 10:19+0300\n" -"Last-Translator: FULL NAME \n" -"Language: ru\n" -"Language-Team: ru \n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" +"PO-Revision-Date: 2020-06-17 12:20+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.8.0\n" +"Language: ru\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: templates/common_meta.html:1 msgid "" -"ClickHouse is a fast open-source column-oriented database management " -"system that allows generating analytical data reports in real-time using " -"SQL queries" +"ClickHouse is a fast open-source column-oriented database management system " +"that allows generating analytical data reports in real-time using SQL queries" msgstr "" -"ClickHouse-это быстрая система управления базами данных с открытым " -"исходным кодом, ориентированная на столбцы, которая позволяет создавать " -"аналитические отчеты о данных в режиме реального времени с использованием" -" SQL-запросов" #: templates/common_meta.html:6 msgid "ClickHouse - fast open-source OLAP DBMS" -msgstr "ClickHouse-быстрая СУБД OLAP с открытым исходным кодом" +msgstr "" #: templates/common_meta.html:10 msgid "ClickHouse DBMS" -msgstr "СУБД ClickHouse" +msgstr "" #: templates/common_meta.html:32 msgid "open-source" -msgstr "открытый исходный код" +msgstr "" #: templates/common_meta.html:32 msgid "relational" -msgstr "реляционный" +msgstr "" #: templates/common_meta.html:32 msgid "analytics" -msgstr "аналитика" +msgstr "" #: templates/common_meta.html:32 msgid "analytical" -msgstr "аналитический" +msgstr "" #: templates/common_meta.html:32 msgid "Big Data" -msgstr "большие данные" +msgstr "" #: templates/common_meta.html:32 msgid "web-analytics" -msgstr "веб-аналитика" +msgstr "" #: templates/footer.html:8 msgid "ClickHouse source code is published under the Apache 2.0 License." -msgstr "Исходный код ClickHouse публикуется под лицензией Apache 2.0." +msgstr "" #: templates/footer.html:8 msgid "" "Software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR " "CONDITIONS OF ANY KIND, either express or implied." msgstr "" -"Программное обеспечение распространяется на условиях \"как есть\", без " -"каких-либо гарантий или условий, явных или подразумеваемых." #: templates/footer.html:11 msgid "Yandex LLC" -msgstr "ООО «Яндекс»" +msgstr "" #: templates/blog/content.html:20 templates/blog/content.html:25 #: templates/blog/content.html:30 msgid "Share on" -msgstr "Поделиться в" +msgstr "" #: templates/blog/content.html:37 msgid "Published date" -msgstr "Дата публикации" +msgstr "" #: templates/blog/nav.html:20 msgid "New post" -msgstr "Новый пост" +msgstr "" #: templates/blog/nav.html:25 msgid "Documentation" -msgstr "Документация" +msgstr "" #: templates/docs/footer.html:3 msgid "Rating" -msgstr "Рейтинг" +msgstr "" #: templates/docs/footer.html:3 msgid "votes" -msgstr "голосов" +msgstr "" #: templates/docs/footer.html:4 msgid "Article Rating" -msgstr "Рейтинг статьи" +msgstr "" #: templates/docs/footer.html:4 msgid "Was this content helpful?" -msgstr "Был ли этот контент полезным?" +msgstr "" #: templates/docs/footer.html:7 msgid "Unusable" -msgstr "Непригодная" +msgstr "" #: templates/docs/footer.html:7 msgid "Poor" -msgstr "Плохая" +msgstr "" #: templates/docs/footer.html:7 msgid "Good" -msgstr "Хорошая" +msgstr "" #: templates/docs/footer.html:7 msgid "Excellent" -msgstr "Отличная" +msgstr "" #: templates/docs/footer.html:8 msgid "documentation" -msgstr "документация" +msgstr "" #: templates/docs/footer.html:15 msgid "Built from" -msgstr "Собрано из" +msgstr "" #: templates/docs/footer.html:15 msgid "published on" -msgstr "опубликовано" +msgstr "" #: templates/docs/footer.html:15 msgid "modified on" -msgstr "изменено" +msgstr "" #: templates/docs/machine-translated.html:3 msgid "Help wanted!" -msgstr "Нужна помощь!" +msgstr "" #: templates/docs/machine-translated.html:4 msgid "" "The following content of this documentation page has been machine-" "translated. But unlike other websites, it is not done on the fly. This " "translated text lives on GitHub repository alongside main ClickHouse " -"codebase and waits for fellow native speakers to make it more human-" -"readable." +"codebase and waits for fellow native speakers to make it more human-readable." msgstr "" -"Нижеследующее содержание этой страницы документации было создано через " -"машинный перевод. Но в отличие от других сайтов, это делается не на лету." -" Этот переведенный текст живет в репозитории GitHub вместе с основной " -"кодовой базой ClickHouse и ждет, когда другие носители языка сделают его " -"более удобочитаемым." #: templates/docs/machine-translated.html:4 msgid "You can also use the original English version as a reference." msgstr "" -"Вы также можете использовать оригинальную английскую версию в качестве " -"образца." #: templates/docs/machine-translated.html:7 msgid "Help ClickHouse documentation by editing this page" -msgstr "Помогите документации ClickHouse, отредактировав эту страницу" +msgstr "" #: templates/docs/sidebar.html:3 msgid "Multi-page or single-page" -msgstr "Многостраничный или одностраничный" +msgstr "" #: templates/docs/sidebar.html:5 msgid "Multi-page version" -msgstr "Многостраничная версия" +msgstr "" #: templates/docs/sidebar.html:8 msgid "Single-page version" -msgstr "Одностраничная версия" +msgstr "" #: templates/docs/sidebar.html:13 msgid "Version" -msgstr "Версия" +msgstr "" #: templates/docs/sidebar.html:13 templates/docs/sidebar.html:19 msgid "latest" -msgstr "последняя" +msgstr "" #: templates/docs/sidebar.html:36 msgid "PDF version" -msgstr "PDF-версия" +msgstr "" #: templates/docs/toc.html:8 msgid "Table of Contents" -msgstr "Cодержание" +msgstr "" #: templates/index/community.html:4 msgid "ClickHouse community" -msgstr "ClickHouse сообщество" +msgstr "" #: templates/index/community.html:13 templates/index/community.html:14 msgid "ClickHouse YouTube Channel" -msgstr "YouTube канал ClickHouse" +msgstr "" #: templates/index/community.html:25 templates/index/community.html:26 msgid "ClickHouse Official Twitter Account" -msgstr "Официальный аккаунт в Twitter" +msgstr "" #: templates/index/community.html:36 templates/index/community.html:37 msgid "ClickHouse at Telegram" -msgstr "ClickHouse в Telegram" +msgstr "" #: templates/index/community.html:41 msgid "Chat with real users in " -msgstr "Чат с другими пользователями " +msgstr "" #: templates/index/community.html:44 templates/index/community.html:116 msgid "English" -msgstr "Английский" +msgstr "" #: templates/index/community.html:45 msgid "or in" -msgstr "или" +msgstr "" #: templates/index/community.html:47 templates/index/community.html:117 msgid "Russian" -msgstr "Русский" +msgstr "" #: templates/index/community.html:65 msgid "Open GitHub issue to ask for help or to file a feature request" -msgstr "В GitHub Issues можно попросить помочь или запросить новую возможность " +msgstr "" #: templates/index/community.html:76 templates/index/community.html:77 msgid "ClickHouse Slack Workspace" -msgstr "ClickHouse Slack" +msgstr "" #: templates/index/community.html:82 msgid "Multipurpose public hangout" -msgstr "Универсальное сообщество" +msgstr "" #: templates/index/community.html:101 msgid "Ask any questions" -msgstr "Задай любые вопросы" +msgstr "" #: templates/index/community.html:115 msgid "ClickHouse Blog" -msgstr "Блог ClickHouse" +msgstr "" #: templates/index/community.html:116 msgid "in" -msgstr "в" +msgstr "" #: templates/index/community.html:128 templates/index/community.html:129 msgid "ClickHouse at Google Groups" -msgstr "ClickHouse в Google Groups" +msgstr "" #: templates/index/community.html:133 msgid "Email discussions" -msgstr "Обсуждения по email" +msgstr "" #: templates/index/community.html:142 msgid "Like ClickHouse?" -msgstr "Нравится ClickHouse?" +msgstr "" #: templates/index/community.html:143 msgid "Help to spread the word about it via" -msgstr "Помоги распространить информацию о нём через" +msgstr "" #: templates/index/community.html:144 msgid "and" -msgstr "и" +msgstr "" #: templates/index/community.html:153 msgid "Hosting ClickHouse Meetups" -msgstr "Проведение ClickHouse митапов" +msgstr "" #: templates/index/community.html:157 msgid "" -"ClickHouse meetups are essential for strengthening community worldwide, " -"but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " -"ClickHouse core team for any other reason." +"ClickHouse meetups are essential for strengthening community worldwide, but " +"they couldn't be possible without the help of local organizers. Please, fill " +"this form if you want to become one or want to meet ClickHouse core team for " +"any other reason." msgstr "" -"Встречи ClickHouse необходимы для укрепления сообщества во всем мире, но " -"они не могут быть возможны без помощи местных организаторов. Пожалуйста, " -"почувствуйте эту форму, если вы хотите стать одним из них или хотите " -"встретиться с основной командой ClickHouse по любой другой причине." #: templates/index/community.html:159 msgid "ClickHouse Meetup" -msgstr "ClickHouse митап" +msgstr "" #: templates/index/community.html:165 msgid "Name" -msgstr "Имя" +msgstr "" #: templates/index/community.html:168 msgid "Email" -msgstr "Email" +msgstr "" #: templates/index/community.html:171 msgid "Company" -msgstr "Компания" +msgstr "" #: templates/index/community.html:174 msgid "City" -msgstr "Город" +msgstr "" #: templates/index/community.html:179 msgid "We'd like to host a public ClickHouse Meetup" -msgstr "Мы хотели бы провести публичный ClickHouse митап" +msgstr "" #: templates/index/community.html:185 msgid "We'd like to invite Yandex ClickHouse team to our office" -msgstr "Мы хотели бы пригласить команду разработки ClickHouse в наш офис" +msgstr "" #: templates/index/community.html:191 msgid "We'd like to invite Yandex ClickHouse team to another event we organize" msgstr "" -"Мы хотели бы пригласить команду разработки ClickHouse на другое " -"мероприятие, которое мы организуем" #: templates/index/community.html:197 msgid "We're interested in commercial consulting, support or managed service" msgstr "" -"Мы заинтересованы в консалтинге, коммерческой поддержке или управляемом " -"сервисе" #: templates/index/community.html:201 msgid "Additional comments" -msgstr "Дополнительный комментарий" +msgstr "" #: templates/index/community.html:203 msgid "Send" -msgstr "Отправить" +msgstr "" #: templates/index/community.html:212 msgid "" "If you have any more thoughts or questions, feel free to contact Yandex " "ClickHouse team directly at" msgstr "" -"Если у вас есть какие-либо мысли или вопросы, не стесняйтесь обращаться в" -" команду ClickHouse в Яндексе напрямую по адресу" #: templates/index/community.html:213 msgid "turn on JavaScript to see email address" -msgstr "включите JavaScript, чтобы увидеть адрес электронной почты" - -#~ msgid "" -#~ "ClickHouse is an open source column-" -#~ "oriented database management system that " -#~ "allows generating analytical data reports " -#~ "in real time using SQL queries." -#~ msgstr "" -#~ "ClickHouse - это ориентированная на " -#~ "столбцы система управления базами данных " -#~ "с открытым исходным кодом, позволяющая " -#~ "создавать аналитические отчеты о данных " -#~ "в режиме реального времени с " -#~ "использованием SQL-запросов." - -#~ msgid "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." -#~ msgstr "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." - -#~ msgid "published at" -#~ msgstr "опубликовано" - -#~ msgid "modified at" -#~ msgstr "изменено" - -#~ msgid "" -#~ "ClickHouse meetups are essential for " -#~ "strengthening community worldwide, but they" -#~ " couldn't be possible without the " -#~ "help of local organizers. Please, fill" -#~ " this form if you want to " -#~ "become one or want to meet " -#~ "ClickHouse core team for any other " -#~ "reason." -#~ msgstr "" -#~ "ClickHouse митапы играют ключевую роль " -#~ "укреплении нашего сообщества во всем " -#~ "мире, но они не могли бы быть " -#~ "возможны без помощи местных организаторов. " -#~ "Пожалуйста, заполните эту форму, если вы" -#~ " хотите стать одним из них или " -#~ "хотите встретиться с командой разработки " -#~ "ClickHouse по любой другой причине." - +msgstr "" diff --git a/website/locale/tr/LC_MESSAGES/messages.mo b/website/locale/tr/LC_MESSAGES/messages.mo index 40351d0eee9..0386bd03351 100644 Binary files a/website/locale/tr/LC_MESSAGES/messages.mo and b/website/locale/tr/LC_MESSAGES/messages.mo differ diff --git a/website/locale/tr/LC_MESSAGES/messages.po b/website/locale/tr/LC_MESSAGES/messages.po index 985666199b8..710ebbdf120 100644 --- a/website/locale/tr/LC_MESSAGES/messages.po +++ b/website/locale/tr/LC_MESSAGES/messages.po @@ -1,381 +1,326 @@ -# Turkish translations for PROJECT. +# Translations template for PROJECT. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2020. +# Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2020-06-17 12:20+0300\n" -"PO-Revision-Date: 2020-04-15 13:17+0000\n" -"Last-Translator: FULL NAME \n" -"Language: tr\n" -"Language-Team: tr \n" -"Plural-Forms: nplurals=1; plural=0\n" +"PO-Revision-Date: 2020-06-17 12:20+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.8.0\n" +"Language: tr\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #: templates/common_meta.html:1 msgid "" -"ClickHouse is a fast open-source column-oriented database management " -"system that allows generating analytical data reports in real-time using " -"SQL queries" +"ClickHouse is a fast open-source column-oriented database management system " +"that allows generating analytical data reports in real-time using SQL queries" msgstr "" -"ClickHouse SQL sorguları kullanarak gerçek zamanlı olarak analitik veri " -"raporları üreten sağlayan hızlı bir açık kaynak sütun odaklı veritabanı " -"yönetim sistemidir" #: templates/common_meta.html:6 msgid "ClickHouse - fast open-source OLAP DBMS" -msgstr "ClickHouse - hızlı açık kaynak OLAP DBMS" +msgstr "" #: templates/common_meta.html:10 msgid "ClickHouse DBMS" -msgstr "ClickHouse DBMS" +msgstr "" #: templates/common_meta.html:32 msgid "open-source" -msgstr "açık kaynak" +msgstr "" #: templates/common_meta.html:32 msgid "relational" -msgstr "ilişkisel" +msgstr "" #: templates/common_meta.html:32 msgid "analytics" -msgstr "analiz" +msgstr "" #: templates/common_meta.html:32 msgid "analytical" -msgstr "analitik" +msgstr "" #: templates/common_meta.html:32 msgid "Big Data" -msgstr "Büyük Veri" +msgstr "" #: templates/common_meta.html:32 msgid "web-analytics" -msgstr "web-analyt -ics" +msgstr "" #: templates/footer.html:8 msgid "ClickHouse source code is published under the Apache 2.0 License." -msgstr "ClickHouse kaynak kodu Apache 2.0 Lisansı altında yayınlandı." +msgstr "" #: templates/footer.html:8 msgid "" "Software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR " "CONDITIONS OF ANY KIND, either express or implied." msgstr "" -"Yazılım \"OLDUĞU GİBİ\" BAZINDA dağıtılır, GARANTİ VEYA HERHANGİ bir şart" -" OLMADAN, Açık veya zımni." #: templates/footer.html:11 msgid "Yandex LLC" -msgstr "Yandex LLC" +msgstr "" #: templates/blog/content.html:20 templates/blog/content.html:25 #: templates/blog/content.html:30 msgid "Share on" -msgstr "Share on" +msgstr "" #: templates/blog/content.html:37 msgid "Published date" -msgstr "Yayım datelandığı tarih" +msgstr "" #: templates/blog/nav.html:20 msgid "New post" -msgstr "Yeni Mesaj" +msgstr "" #: templates/blog/nav.html:25 msgid "Documentation" -msgstr "Belge" +msgstr "" #: templates/docs/footer.html:3 msgid "Rating" -msgstr "Verim" +msgstr "" #: templates/docs/footer.html:3 msgid "votes" -msgstr "oylar" +msgstr "" #: templates/docs/footer.html:4 msgid "Article Rating" -msgstr "Makale Değerlendirme" +msgstr "" #: templates/docs/footer.html:4 msgid "Was this content helpful?" -msgstr "Bu içerik yararlı mıydı?" +msgstr "" #: templates/docs/footer.html:7 msgid "Unusable" -msgstr "Kullanışsız" +msgstr "" #: templates/docs/footer.html:7 msgid "Poor" -msgstr "Zavallı" +msgstr "" #: templates/docs/footer.html:7 msgid "Good" -msgstr "İyi" +msgstr "" #: templates/docs/footer.html:7 msgid "Excellent" -msgstr "Mükemmel" +msgstr "" #: templates/docs/footer.html:8 msgid "documentation" -msgstr "belge" +msgstr "" #: templates/docs/footer.html:15 msgid "Built from" -msgstr "Dahili" +msgstr "" #: templates/docs/footer.html:15 msgid "published on" -msgstr "yayınlanan" +msgstr "" #: templates/docs/footer.html:15 msgid "modified on" -msgstr "modifiye on" +msgstr "" #: templates/docs/machine-translated.html:3 msgid "Help wanted!" -msgstr "Yardım istedi!" +msgstr "" #: templates/docs/machine-translated.html:4 msgid "" "The following content of this documentation page has been machine-" "translated. But unlike other websites, it is not done on the fly. This " "translated text lives on GitHub repository alongside main ClickHouse " -"codebase and waits for fellow native speakers to make it more human-" -"readable." +"codebase and waits for fellow native speakers to make it more human-readable." msgstr "" -"Bu Dokümantasyon sayfasının aşağıdaki içeriği makine tarafından " -"çevrilmiştir. Ancak diğer web sitelerinin aksine, anında yapılmaz. Bu " -"çevrilmiş metin, ana ClickHouse kod tabanının yanında GitHub deposunda " -"yaşar ve diğer anadili konuşanların daha insan tarafından okunabilir " -"olmasını bekler." #: templates/docs/machine-translated.html:4 msgid "You can also use the original English version as a reference." -msgstr "Orijinal İngilizce sürümünü referans olarak da kullanabilirsiniz." +msgstr "" #: templates/docs/machine-translated.html:7 msgid "Help ClickHouse documentation by editing this page" -msgstr "Bu sayfayı düzenleyerek ClickHouse belgelerine yardım edin" +msgstr "" #: templates/docs/sidebar.html:3 msgid "Multi-page or single-page" -msgstr "Çok sayfalı veya tek sayfalı" +msgstr "" #: templates/docs/sidebar.html:5 msgid "Multi-page version" -msgstr "Çok sayfalı sürüm" +msgstr "" #: templates/docs/sidebar.html:8 msgid "Single-page version" -msgstr "Tek sayfalık sürüm" +msgstr "" #: templates/docs/sidebar.html:13 msgid "Version" -msgstr "Sürüm" +msgstr "" #: templates/docs/sidebar.html:13 templates/docs/sidebar.html:19 msgid "latest" -msgstr "son" +msgstr "" #: templates/docs/sidebar.html:36 msgid "PDF version" -msgstr "PDF versiyonu" +msgstr "" #: templates/docs/toc.html:8 msgid "Table of Contents" -msgstr "İçindekiler tablosu" +msgstr "" #: templates/index/community.html:4 msgid "ClickHouse community" -msgstr "ClickHouse topluluğu" +msgstr "" #: templates/index/community.html:13 templates/index/community.html:14 msgid "ClickHouse YouTube Channel" -msgstr "ClickHouse YouTube Kanalı" +msgstr "" #: templates/index/community.html:25 templates/index/community.html:26 msgid "ClickHouse Official Twitter Account" -msgstr "ClickHouse Resmi Twitter Hesabı" +msgstr "" #: templates/index/community.html:36 templates/index/community.html:37 msgid "ClickHouse at Telegram" -msgstr "Telegram'da ClickHouse" +msgstr "" #: templates/index/community.html:41 msgid "Chat with real users in " -msgstr "Gerçek kullanıcılar ile sohbet " +msgstr "" #: templates/index/community.html:44 templates/index/community.html:116 msgid "English" -msgstr "İngilizce" +msgstr "" #: templates/index/community.html:45 msgid "or in" -msgstr "veya içinde" +msgstr "" #: templates/index/community.html:47 templates/index/community.html:117 msgid "Russian" -msgstr "Rusça" +msgstr "" #: templates/index/community.html:65 msgid "Open GitHub issue to ask for help or to file a feature request" -msgstr "Yardım istemek veya bir özellik isteği göndermek için GitHub sorununu açın" +msgstr "" #: templates/index/community.html:76 templates/index/community.html:77 msgid "ClickHouse Slack Workspace" -msgstr "ClickHouse Slack Çalışma Alanı" +msgstr "" #: templates/index/community.html:82 msgid "Multipurpose public hangout" -msgstr "Çok amaçlı kamu hangout" +msgstr "" #: templates/index/community.html:101 msgid "Ask any questions" -msgstr "Herhangi bir soru sorun" +msgstr "" #: templates/index/community.html:115 msgid "ClickHouse Blog" -msgstr "ClickHouse Blog" +msgstr "" #: templates/index/community.html:116 msgid "in" -msgstr "içinde" +msgstr "" #: templates/index/community.html:128 templates/index/community.html:129 msgid "ClickHouse at Google Groups" -msgstr "Google Grupları'nda ClickHouse" +msgstr "" #: templates/index/community.html:133 msgid "Email discussions" -msgstr "E-posta tartış discussionsmaları" +msgstr "" #: templates/index/community.html:142 msgid "Like ClickHouse?" -msgstr "ClickHouse Gibi Mi?" +msgstr "" #: templates/index/community.html:143 msgid "Help to spread the word about it via" -msgstr "Aracılığıyla bu konuda kelime yaymak için yardım" +msgstr "" #: templates/index/community.html:144 msgid "and" -msgstr "ve" +msgstr "" #: templates/index/community.html:153 msgid "Hosting ClickHouse Meetups" -msgstr "ClickHouse Buluşmaları Barındırma" +msgstr "" #: templates/index/community.html:157 msgid "" -"ClickHouse meetups are essential for strengthening community worldwide, " -"but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " -"ClickHouse core team for any other reason." +"ClickHouse meetups are essential for strengthening community worldwide, but " +"they couldn't be possible without the help of local organizers. Please, fill " +"this form if you want to become one or want to meet ClickHouse core team for " +"any other reason." msgstr "" -"ClickHouse buluşmalar dünya çapında toplumu güçlendirmek için gereklidir," -" ancak yerel organizatörlerin yardımı olmadan mümkün olamazdı. Eğer biri " -"olmak istiyorsanız veya başka bir nedenle ClickHouse çekirdek ekibi " -"karşılamak istiyorsanız, bu formu hissedin." #: templates/index/community.html:159 msgid "ClickHouse Meetup" -msgstr "ClickHouse Meetup" +msgstr "" #: templates/index/community.html:165 msgid "Name" -msgstr "Ad" +msgstr "" #: templates/index/community.html:168 msgid "Email" -msgstr "Posta" +msgstr "" #: templates/index/community.html:171 msgid "Company" -msgstr "Şirket" +msgstr "" #: templates/index/community.html:174 msgid "City" -msgstr "Şehir" +msgstr "" #: templates/index/community.html:179 msgid "We'd like to host a public ClickHouse Meetup" -msgstr "Halka açık bir ClickHouse buluşmasına ev sahipliği yapmak istiyoruz" +msgstr "" #: templates/index/community.html:185 msgid "We'd like to invite Yandex ClickHouse team to our office" -msgstr "Yandex ClickHouse ekibini ofisimize davet etmek istiyoruz" +msgstr "" #: templates/index/community.html:191 msgid "We'd like to invite Yandex ClickHouse team to another event we organize" msgstr "" -"Yandex ClickHouse ekibini organize ettiğimiz başka bir etkinliğe davet " -"etmek istiyoruz" #: templates/index/community.html:197 msgid "We're interested in commercial consulting, support or managed service" -msgstr "Ticari danışmanlık, destek veya yönetilen hizmetle ilgileniyoruz" +msgstr "" #: templates/index/community.html:201 msgid "Additional comments" -msgstr "Ek yorumlar" +msgstr "" #: templates/index/community.html:203 msgid "Send" -msgstr "Göndermek" +msgstr "" #: templates/index/community.html:212 msgid "" "If you have any more thoughts or questions, feel free to contact Yandex " "ClickHouse team directly at" msgstr "" -"Daha fazla düşünceniz veya sorunuz varsa, Yandex ClickHouse ekibiyle " -"doğrudan iletişime geçmekten çekinmeyin" #: templates/index/community.html:213 msgid "turn on JavaScript to see email address" -msgstr "e-posta adresini görmek için JavaScript'i açın" - -#~ msgid "" -#~ "ClickHouse is an open source column-" -#~ "oriented database management system that " -#~ "allows generating analytical data reports " -#~ "in real time using SQL queries." -#~ msgstr "" -#~ "ClickHouse SQL sorguları kullanarak gerçek " -#~ "zamanlı olarak analitik veri raporları " -#~ "üreten sağlayan bir açık kaynak sütun" -#~ " odaklı veritabanı yönetim sistemidir." - -#~ msgid "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." -#~ msgstr "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." - -#~ msgid "published at" -#~ msgstr "yayınlanan at" - -#~ msgid "modified at" -#~ msgstr "modifiye at" - +msgstr "" diff --git a/website/locale/zh/LC_MESSAGES/messages.mo b/website/locale/zh/LC_MESSAGES/messages.mo index 21279487e89..c5c8a3ba501 100644 Binary files a/website/locale/zh/LC_MESSAGES/messages.mo and b/website/locale/zh/LC_MESSAGES/messages.mo differ diff --git a/website/locale/zh/LC_MESSAGES/messages.po b/website/locale/zh/LC_MESSAGES/messages.po index 5625d79f77e..77683ea398d 100644 --- a/website/locale/zh/LC_MESSAGES/messages.po +++ b/website/locale/zh/LC_MESSAGES/messages.po @@ -1,363 +1,325 @@ -# Chinese translations for PROJECT. +# Translations template for PROJECT. # Copyright (C) 2020 ORGANIZATION # This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2020. +# Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2020-06-17 12:20+0300\n" -"PO-Revision-Date: 2020-03-26 10:19+0300\n" -"Last-Translator: FULL NAME \n" -"Language: zh\n" -"Language-Team: zh \n" -"Plural-Forms: nplurals=1; plural=0\n" +"PO-Revision-Date: 2020-06-17 12:20+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.8.0\n" +"Language: zh\n" #: templates/common_meta.html:1 msgid "" -"ClickHouse is a fast open-source column-oriented database management " -"system that allows generating analytical data reports in real-time using " -"SQL queries" -msgstr "ClickHouse是一个快速开源的面向列的数据库管理系统,允许使用SQL查询实时生成分析数据报告" +"ClickHouse is a fast open-source column-oriented database management system " +"that allows generating analytical data reports in real-time using SQL queries" +msgstr "" #: templates/common_meta.html:6 msgid "ClickHouse - fast open-source OLAP DBMS" -msgstr "ツ暗ェツ氾环催ツ団ツ法ツ人" +msgstr "" #: templates/common_meta.html:10 msgid "ClickHouse DBMS" -msgstr "ツ环板msョツ嘉ッツ偲" +msgstr "" #: templates/common_meta.html:32 msgid "open-source" -msgstr "开源" +msgstr "" #: templates/common_meta.html:32 msgid "relational" -msgstr "关系" +msgstr "" #: templates/common_meta.html:32 msgid "analytics" -msgstr "分析" +msgstr "" #: templates/common_meta.html:32 msgid "analytical" -msgstr "分析" +msgstr "" #: templates/common_meta.html:32 msgid "Big Data" -msgstr "大数据" +msgstr "" #: templates/common_meta.html:32 msgid "web-analytics" -msgstr "网络分析" +msgstr "" #: templates/footer.html:8 msgid "ClickHouse source code is published under the Apache 2.0 License." -msgstr "ClickHouse源代码是在Apache2.0许可下发布的。" +msgstr "" #: templates/footer.html:8 msgid "" "Software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR " "CONDITIONS OF ANY KIND, either express or implied." -msgstr "软件按\"原样\"分发,不附带任何明示或暗示的担保或条件。" +msgstr "" #: templates/footer.html:11 msgid "Yandex LLC" -msgstr "Yandex LLC" +msgstr "" #: templates/blog/content.html:20 templates/blog/content.html:25 #: templates/blog/content.html:30 msgid "Share on" -msgstr "分享到" +msgstr "" #: templates/blog/content.html:37 msgid "Published date" -msgstr "发布日期" +msgstr "" #: templates/blog/nav.html:20 msgid "New post" -msgstr "新帖子" +msgstr "" #: templates/blog/nav.html:25 msgid "Documentation" -msgstr "文件" +msgstr "" #: templates/docs/footer.html:3 msgid "Rating" -msgstr "评分" +msgstr "" #: templates/docs/footer.html:3 msgid "votes" -msgstr "所得票数" +msgstr "" #: templates/docs/footer.html:4 msgid "Article Rating" -msgstr "文章评级" +msgstr "" #: templates/docs/footer.html:4 msgid "Was this content helpful?" -msgstr "这个内容有帮助??" +msgstr "" #: templates/docs/footer.html:7 msgid "Unusable" -msgstr "无法使用" +msgstr "" #: templates/docs/footer.html:7 msgid "Poor" -msgstr "差" +msgstr "" #: templates/docs/footer.html:7 msgid "Good" -msgstr "很好" +msgstr "" #: templates/docs/footer.html:7 msgid "Excellent" -msgstr "善乎哉!" +msgstr "" #: templates/docs/footer.html:8 msgid "documentation" -msgstr "文件" +msgstr "" #: templates/docs/footer.html:15 msgid "Built from" -msgstr "建于" +msgstr "" #: templates/docs/footer.html:15 msgid "published on" -msgstr "发表于" +msgstr "" #: templates/docs/footer.html:15 msgid "modified on" -msgstr "修改于" +msgstr "" #: templates/docs/machine-translated.html:3 msgid "Help wanted!" -msgstr "帮助通缉!" +msgstr "" #: templates/docs/machine-translated.html:4 msgid "" "The following content of this documentation page has been machine-" "translated. But unlike other websites, it is not done on the fly. This " "translated text lives on GitHub repository alongside main ClickHouse " -"codebase and waits for fellow native speakers to make it more human-" -"readable." +"codebase and waits for fellow native speakers to make it more human-readable." msgstr "" -"本文档页面的以下内容已经过机器翻译。 但与其他网站不同,它不是在飞行中完成。 " -"这个翻译的文本生活在github存储库旁边的主ClickHouse代码库,并等待同胞母语,使其更具人类可读性。" #: templates/docs/machine-translated.html:4 msgid "You can also use the original English version as a reference." -msgstr "您也可以使用原始的英文版本作为参考。" +msgstr "" #: templates/docs/machine-translated.html:7 msgid "Help ClickHouse documentation by editing this page" -msgstr "通过编辑此页面帮助ClickHouse文档" +msgstr "" #: templates/docs/sidebar.html:3 msgid "Multi-page or single-page" -msgstr "多页或单页" +msgstr "" #: templates/docs/sidebar.html:5 msgid "Multi-page version" -msgstr "多页版本" +msgstr "" #: templates/docs/sidebar.html:8 msgid "Single-page version" -msgstr "单页版本" +msgstr "" #: templates/docs/sidebar.html:13 msgid "Version" -msgstr "版本" +msgstr "" #: templates/docs/sidebar.html:13 templates/docs/sidebar.html:19 msgid "latest" -msgstr "最新消息" +msgstr "" #: templates/docs/sidebar.html:36 msgid "PDF version" -msgstr "PDF版本" +msgstr "" #: templates/docs/toc.html:8 msgid "Table of Contents" -msgstr "目录" +msgstr "" #: templates/index/community.html:4 msgid "ClickHouse community" -msgstr "ツ环板communityョツ嘉ッ" +msgstr "" #: templates/index/community.html:13 templates/index/community.html:14 msgid "ClickHouse YouTube Channel" -msgstr "ツ环板Channelョツ嘉ッツ偲" +msgstr "" #: templates/index/community.html:25 templates/index/community.html:26 msgid "ClickHouse Official Twitter Account" -msgstr "ツ环板Officialョツ嘉ッ" +msgstr "" #: templates/index/community.html:36 templates/index/community.html:37 msgid "ClickHouse at Telegram" -msgstr "ツ环板atョツ嘉ッツ偲" +msgstr "" #: templates/index/community.html:41 msgid "Chat with real users in " -msgstr "与真正的用户聊天 " +msgstr "" #: templates/index/community.html:44 templates/index/community.html:116 msgid "English" -msgstr "英语" +msgstr "" #: templates/index/community.html:45 msgid "or in" -msgstr "或在" +msgstr "" #: templates/index/community.html:47 templates/index/community.html:117 msgid "Russian" -msgstr "俄语" +msgstr "" #: templates/index/community.html:65 msgid "Open GitHub issue to ask for help or to file a feature request" -msgstr "打开GitHub问题以寻求帮助或提交功能请求" +msgstr "" #: templates/index/community.html:76 templates/index/community.html:77 msgid "ClickHouse Slack Workspace" -msgstr "ツ环板Workspaceョツ嘉ッツ偲" +msgstr "" #: templates/index/community.html:82 msgid "Multipurpose public hangout" -msgstr "多用途公共聚会" +msgstr "" #: templates/index/community.html:101 msgid "Ask any questions" -msgstr "问任何问题" +msgstr "" #: templates/index/community.html:115 msgid "ClickHouse Blog" -msgstr "ツ环板Blogョツ嘉ッ" +msgstr "" #: templates/index/community.html:116 msgid "in" -msgstr "在" +msgstr "" #: templates/index/community.html:128 templates/index/community.html:129 msgid "ClickHouse at Google Groups" -msgstr "点击屋在谷歌组" +msgstr "" #: templates/index/community.html:133 msgid "Email discussions" -msgstr "电子邮件讨论" +msgstr "" #: templates/index/community.html:142 msgid "Like ClickHouse?" -msgstr "像克里克豪斯?" +msgstr "" #: templates/index/community.html:143 msgid "Help to spread the word about it via" -msgstr "帮助通过传播这个词" +msgstr "" #: templates/index/community.html:144 msgid "and" -msgstr "和" +msgstr "" #: templates/index/community.html:153 msgid "Hosting ClickHouse Meetups" -msgstr "碌莽禄Hosting拢Hosting0755-88888888" +msgstr "" #: templates/index/community.html:157 msgid "" -"ClickHouse meetups are essential for strengthening community worldwide, " -"but they couldn't be possible without the help of local organizers. " -"Please, feel this form if you want to become one or want to meet " -"ClickHouse core team for any other reason." +"ClickHouse meetups are essential for strengthening community worldwide, but " +"they couldn't be possible without the help of local organizers. Please, fill " +"this form if you want to become one or want to meet ClickHouse core team for " +"any other reason." msgstr "" -"ClickHouse聚会对于加强全球社区至关重要,但如果没有当地组织者的帮助,这些聚会是不可能的。 " -"请,感受这种形式,如果你想成为一个或想满足ClickHouse核心团队出于任何其他原因." #: templates/index/community.html:159 msgid "ClickHouse Meetup" -msgstr "ツ环板upョツ嘉ッツ偲" +msgstr "" #: templates/index/community.html:165 msgid "Name" -msgstr "名称" +msgstr "" #: templates/index/community.html:168 msgid "Email" -msgstr "碌莽禄Email:" +msgstr "" #: templates/index/community.html:171 msgid "Company" -msgstr "公司简介" +msgstr "" #: templates/index/community.html:174 msgid "City" -msgstr "城市" +msgstr "" #: templates/index/community.html:179 msgid "We'd like to host a public ClickHouse Meetup" -msgstr "我们想举办一个公共ClickHouse聚会" +msgstr "" #: templates/index/community.html:185 msgid "We'd like to invite Yandex ClickHouse team to our office" -msgstr "我们想邀请Yandex ClickHouse团队到我们的办公室" +msgstr "" #: templates/index/community.html:191 msgid "We'd like to invite Yandex ClickHouse team to another event we organize" -msgstr "我们想邀请Yandex ClickHouse团队参加我们组织的另一个活动" +msgstr "" #: templates/index/community.html:197 msgid "We're interested in commercial consulting, support or managed service" -msgstr "我们对商业咨询、支持或托管服务感兴趣" +msgstr "" #: templates/index/community.html:201 msgid "Additional comments" -msgstr "其他评论" +msgstr "" #: templates/index/community.html:203 msgid "Send" -msgstr "发送" +msgstr "" #: templates/index/community.html:212 msgid "" "If you have any more thoughts or questions, feel free to contact Yandex " "ClickHouse team directly at" -msgstr "如果您有任何更多的想法或问题,请随时直接联系Yandex ClickHouse团队" +msgstr "" #: templates/index/community.html:213 msgid "turn on JavaScript to see email address" -msgstr "打开JavaScript查看电子邮件地址" - -#~ msgid "" -#~ "ClickHouse is an open source column-" -#~ "oriented database management system that " -#~ "allows generating analytical data reports " -#~ "in real time using SQL queries." -#~ msgstr "ClickHouse是一个开源的面向列的数据库管理系统,允许使用SQL查询实时生成分析数据报告。" - -#~ msgid "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." -#~ msgstr "" -#~ "ClickHouse is an open source distributed" -#~ " column-oriented database management system" -#~ " that allows generating analytical data " -#~ "reports in real time using SQL " -#~ "queries. Сreated by Yandex ClickHouse " -#~ "manages extremely large volumes of data" -#~ " in a stable and sustainable manner." - -#~ msgid "published at" -#~ msgstr "发表于" - -#~ msgid "modified at" -#~ msgstr "修改时" - +msgstr "" diff --git a/website/templates/index/community.html b/website/templates/index/community.html index 7ca09e1db20..e65f9ff0f86 100644 --- a/website/templates/index/community.html +++ b/website/templates/index/community.html @@ -151,7 +151,7 @@

- {{ _('ClickHouse meetups are essential for strengthening community worldwide, but they couldn\'t be possible without the help of local organizers. Please, feel this form if you want to become one or want to meet ClickHouse core team for any other reason.') }} + {{ _('ClickHouse meetups are essential for strengthening community worldwide, but they couldn\'t be possible without the help of local organizers. Please, fill this form if you want to become one or want to meet ClickHouse core team for any other reason.') }}

{{ _('ClickHouse Meetup') }}