diff --git a/be/src/common/config.cpp b/be/src/common/config.cpp index 5c177e1d88..fec4662cd4 100644 --- a/be/src/common/config.cpp +++ b/be/src/common/config.cpp @@ -1035,6 +1035,15 @@ DEFINE_mInt64(kerberos_expiration_time_seconds, "43200"); DEFINE_mString(get_stack_trace_tool, "libunwind"); +// the ratio of _prefetch_size/_batch_size in AutoIncIDBuffer +DEFINE_mInt64(auto_inc_prefetch_size_ratio, "10"); + +// the ratio of _low_level_water_level_mark/_batch_size in AutoIncIDBuffer +DEFINE_mInt64(auto_inc_low_water_level_mark_size_ratio, "3"); + +// number of threads that fetch auto-inc ranges from FE +DEFINE_mInt64(auto_inc_fetch_thread_num, "3"); + #ifdef BE_TEST // test s3 DEFINE_String(test_s3_resource, "resource"); diff --git a/be/src/common/config.h b/be/src/common/config.h index b572aecfe7..50b391ff4b 100644 --- a/be/src/common/config.h +++ b/be/src/common/config.h @@ -1062,6 +1062,15 @@ DECLARE_mInt64(kerberos_expiration_time_seconds); // Values include `none`, `glog`, `boost`, `glibc`, `libunwind` DECLARE_mString(get_stack_trace_tool); +// the ratio of _prefetch_size/_batch_size in AutoIncIDBuffer +DECLARE_mInt64(auto_inc_prefetch_size_ratio); + +// the ratio of _low_level_water_level_mark/_batch_size in AutoIncIDBuffer +DECLARE_mInt64(auto_inc_low_water_level_mark_size_ratio); + +// number of threads that fetch auto-inc ranges from FE +DECLARE_mInt64(auto_inc_fetch_thread_num); + #ifdef BE_TEST // test s3 DECLARE_String(test_s3_resource); diff --git a/be/src/runtime/descriptors.cpp b/be/src/runtime/descriptors.cpp index 1855f5d58d..73bde2ba9d 100644 --- a/be/src/runtime/descriptors.cpp +++ b/be/src/runtime/descriptors.cpp @@ -63,7 +63,8 @@ SlotDescriptor::SlotDescriptor(const TSlotDescriptor& tdesc) _field_idx(-1), _is_materialized(tdesc.isMaterialized), _is_key(tdesc.is_key), - _need_materialize(tdesc.need_materialize) {} + _need_materialize(tdesc.need_materialize), + _is_auto_increment(tdesc.__isset.is_auto_increment ? tdesc.is_auto_increment : false) {} SlotDescriptor::SlotDescriptor(const PSlotDescriptor& pdesc) : _id(pdesc.id()), @@ -78,7 +79,8 @@ SlotDescriptor::SlotDescriptor(const PSlotDescriptor& pdesc) _field_idx(-1), _is_materialized(pdesc.is_materialized()), _is_key(pdesc.is_key()), - _need_materialize(true) {} + _need_materialize(true), + _is_auto_increment(pdesc.is_auto_increment()) {} void SlotDescriptor::to_protobuf(PSlotDescriptor* pslot) const { pslot->set_id(_id); @@ -94,6 +96,7 @@ void SlotDescriptor::to_protobuf(PSlotDescriptor* pslot) const { pslot->set_is_materialized(_is_materialized); pslot->set_col_unique_id(_col_unique_id); pslot->set_is_key(_is_key); + pslot->set_is_auto_increment(_is_auto_increment); } vectorized::MutableColumnPtr SlotDescriptor::get_empty_mutable_column() const { diff --git a/be/src/runtime/descriptors.h b/be/src/runtime/descriptors.h index aff3b03a0f..2d9ecf9a32 100644 --- a/be/src/runtime/descriptors.h +++ b/be/src/runtime/descriptors.h @@ -109,6 +109,8 @@ public: bool is_key() const { return _is_key; } bool need_materialize() const { return _need_materialize; } + bool is_auto_increment() const { return _is_auto_increment; } + private: friend class DescriptorTbl; friend class TupleDescriptor; @@ -142,6 +144,8 @@ private: const bool _is_key; const bool _need_materialize; + const bool _is_auto_increment; + SlotDescriptor(const TSlotDescriptor& tdesc); SlotDescriptor(const PSlotDescriptor& pdesc); }; diff --git a/be/src/vec/sink/autoinc_buffer.cpp b/be/src/vec/sink/autoinc_buffer.cpp new file mode 100644 index 0000000000..69c245668a --- /dev/null +++ b/be/src/vec/sink/autoinc_buffer.cpp @@ -0,0 +1,129 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include "vec/sink/autoinc_buffer.h" + +#include + +#include "runtime/client_cache.h" +#include "runtime/exec_env.h" +#include "util/runtime_profile.h" +#include "util/thrift_rpc_helper.h" +#include "vec/sink/vtablet_block_convertor.h" + +namespace doris { +namespace stream_load { + +FetchAutoIncIDExecutor::FetchAutoIncIDExecutor() { + ThreadPoolBuilder("AsyncFetchAutoIncIDExecutor") + .set_min_threads(config::auto_inc_fetch_thread_num) + .set_max_threads(config::auto_inc_fetch_thread_num) + .set_max_queue_size(std::numeric_limits::max()) + .build(&_pool); +} + +AutoIncIDBuffer::AutoIncIDBuffer(int64_t db_id, int64_t table_id, int64_t column_id) + : _db_id(db_id), + _table_id(table_id), + _column_id(column_id), + _rpc_token(FetchAutoIncIDExecutor::GetInstance()->_pool->new_token( + ThreadPool::ExecutionMode::CONCURRENT)) {} + +void AutoIncIDBuffer::set_batch_size_at_least(size_t batch_size) { + if (batch_size > _batch_size) { + _batch_size = batch_size; + } +} + +void AutoIncIDBuffer::_wait_for_prefetching() { + if (_is_fetching) { + _rpc_token->wait(); + } +} + +Status AutoIncIDBuffer::sync_request_ids(size_t length, + std::vector>* result) { + std::unique_lock lock(_mutex); + _prefetch_ids(_prefetch_size()); + if (_front_buffer.second > 0) { + auto min_length = std::min(_front_buffer.second, length); + length -= min_length; + result->emplace_back(_front_buffer.first, min_length); + _front_buffer.first += min_length; + _front_buffer.second -= min_length; + } + if (length > 0) { + _wait_for_prefetching(); + if (_rpc_status != Status::OK()) { + return _rpc_status; + } + + { + std::lock_guard lock(_backend_buffer_latch); + std::swap(_front_buffer, _backend_buffer); + } + + DCHECK(length <= _front_buffer.second); + result->emplace_back(_front_buffer.first, length); + _front_buffer.first += length; + _front_buffer.second -= length; + } + return Status::OK(); +} + +void AutoIncIDBuffer::_prefetch_ids(size_t length) { + if (_front_buffer.second > _low_water_level_mark() || _is_fetching) { + return; + } + TNetworkAddress master_addr = ExecEnv::GetInstance()->master_info()->network_address; + _is_fetching = true; + _rpc_token->submit_func([=, this]() { + TAutoIncrementRangeRequest request; + TAutoIncrementRangeResult result; + request.__set_db_id(_db_id); + request.__set_table_id(_table_id); + request.__set_column_id(_column_id); + request.__set_length(length); + + int64_t get_auto_inc_range_rpc_ns; + { + SCOPED_RAW_TIMER(&get_auto_inc_range_rpc_ns); + _rpc_status = ThriftRpcHelper::rpc( + master_addr.hostname, master_addr.port, + [&request, &result](FrontendServiceConnection& client) { + client->getAutoIncrementRange(result, request); + }); + } + LOG(INFO) << "[auto-inc-range][start=" << result.start << ",length=" << result.length + << "][elapsed=" << get_auto_inc_range_rpc_ns / 1000000 << " ms]"; + + if (!_rpc_status.ok() || result.length <= 0) { + LOG(WARNING) << "Failed to fetch auto-incremnt range, encounter rpc failure." + << "errmsg=" << _rpc_status.to_string(); + return; + } + + { + std::lock_guard lock(_backend_buffer_latch); + _backend_buffer = {result.start, result.length}; + } + _is_fetching = false; + }); +} + +} // namespace stream_load +} // namespace doris \ No newline at end of file diff --git a/be/src/vec/sink/autoinc_buffer.h b/be/src/vec/sink/autoinc_buffer.h new file mode 100644 index 0000000000..870418c0de --- /dev/null +++ b/be/src/vec/sink/autoinc_buffer.h @@ -0,0 +1,130 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#pragma once +#include + +#include "common/config.h" +#include "common/status.h" +#include "util/threadpool.h" + +namespace doris { +namespace stream_load { + +class VOlapTableSink; +class OlapTableBlockConvertor; + +struct FetchAutoIncIDExecutor { + FetchAutoIncIDExecutor(); + static FetchAutoIncIDExecutor* GetInstance() { + static FetchAutoIncIDExecutor instance; + return &instance; + } + + std::unique_ptr _pool; +}; + +struct AutoIncIDAllocator { + int64_t next_id() { + DCHECK(!ids.empty()); + if (ids.front().second > 0) { + --ids.front().second; + --total_count; + return ids.front().first++; + } + ids.pop_front(); + DCHECK(!ids.empty() && ids.front().second > 0); + --ids.front().second; + --total_count; + return ids.front().first++; + } + + void insert_ids(int64_t start, size_t length) { + total_count += length; + ids.emplace_back(start, length); + } + + size_t total_count {0}; + std::list> ids; +}; + +class AutoIncIDBuffer { + // GenericReader::_MIN_BATCH_SIZE = 4064 + static constexpr size_t MIN_BATCH_SIZE = 4064; + +public: + // all public functions are thread safe + AutoIncIDBuffer(int64_t _db_id, int64_t _table_id, int64_t column_id); + void set_batch_size_at_least(size_t batch_size); + Status sync_request_ids(size_t length, std::vector>* result); + +private: + void _prefetch_ids(size_t length); + [[nodiscard]] size_t _prefetch_size() const { + return _batch_size * config::auto_inc_prefetch_size_ratio; + } + [[nodiscard]] size_t _low_water_level_mark() const { + return _batch_size * config::auto_inc_low_water_level_mark_size_ratio; + }; + void _wait_for_prefetching(); + + std::atomic _batch_size {MIN_BATCH_SIZE}; + + int64_t _db_id; + int64_t _table_id; + int64_t _column_id; + + std::unique_ptr _rpc_token; + Status _rpc_status {Status::OK()}; + std::atomic _is_fetching {false}; + + std::pair _front_buffer {0, 0}; + std::pair _backend_buffer {0, 0}; + std::mutex _backend_buffer_latch; // for _backend_buffer + std::mutex _mutex; +}; + +class GlobalAutoIncBuffers { +public: + static GlobalAutoIncBuffers* GetInstance() { + static GlobalAutoIncBuffers buffers; + return &buffers; + } + + ~GlobalAutoIncBuffers() { + for (auto [_, buffer] : _buffers) { + delete buffer; + } + } + + AutoIncIDBuffer* get_auto_inc_buffer(int64_t db_id, int64_t table_id, int64_t column_id) { + std::lock_guard lock(_mutex); + auto key = std::make_tuple(db_id, table_id, column_id); + auto it = _buffers.find(key); + if (it == _buffers.end()) { + _buffers.emplace(std::make_pair(key, new AutoIncIDBuffer(db_id, table_id, column_id))); + } + return _buffers[{db_id, table_id, column_id}]; + } + +private: + std::map, AutoIncIDBuffer*> _buffers; + std::mutex _mutex; +}; + +} // namespace stream_load +} // namespace doris \ No newline at end of file diff --git a/be/src/vec/sink/vtablet_block_convertor.cpp b/be/src/vec/sink/vtablet_block_convertor.cpp index 42e1b48d15..16b8ec465b 100644 --- a/be/src/vec/sink/vtablet_block_convertor.cpp +++ b/be/src/vec/sink/vtablet_block_convertor.cpp @@ -18,6 +18,7 @@ #include "vec/sink/vtablet_block_convertor.h" #include +#include #include #include @@ -57,7 +58,7 @@ namespace stream_load { Status OlapTableBlockConvertor::validate_and_convert_block( RuntimeState* state, vectorized::Block* input_block, std::shared_ptr& block, vectorized::VExprContextSPtrs output_vexpr_ctxs, - bool& has_filtered_rows) { + size_t rows, bool eos, bool& has_filtered_rows) { DCHECK(input_block->rows() > 0); block = vectorized::Block::create_shared(input_block->get_columns_with_type_and_name()); @@ -67,6 +68,11 @@ Status OlapTableBlockConvertor::validate_and_convert_block( output_vexpr_ctxs, *input_block, block.get())); } + // fill the valus for auto-increment columns + if (_auto_inc_col_idx.has_value()) { + RETURN_IF_ERROR(_fill_auto_inc_cols(block.get(), rows, eos)); + } + int64_t filtered_rows = 0; { SCOPED_RAW_TIMER(&_validate_data_ns); @@ -86,6 +92,19 @@ Status OlapTableBlockConvertor::validate_and_convert_block( return Status::OK(); } +void OlapTableBlockConvertor::init_autoinc_info(int64_t db_id, int64_t table_id, int batch_size) { + _batch_size = batch_size; + for (size_t idx = 0; idx < _output_tuple_desc->slots().size(); idx++) { + if (_output_tuple_desc->slots()[idx]->is_auto_increment()) { + _auto_inc_col_idx = idx; + _auto_inc_id_buffer = GlobalAutoIncBuffers::GetInstance()->get_auto_inc_buffer( + db_id, table_id, _output_tuple_desc->slots()[idx]->col_unique_id()); + _auto_inc_id_buffer->set_batch_size_at_least(_batch_size); + break; + } + } +} + template DecimalV2Value OlapTableBlockConvertor::_get_decimalv2_min_or_max(const TypeDescriptor& type) { std::map, DecimalV2Value>* pmap; @@ -431,5 +450,42 @@ void OlapTableBlockConvertor::_convert_to_dest_desc_block(doris::vectorized::Blo } } +Status OlapTableBlockConvertor::_fill_auto_inc_cols(vectorized::Block* block, size_t rows, + bool eos) { + size_t idx = _auto_inc_col_idx.value(); + SlotDescriptor* slot = _output_tuple_desc->slots()[idx]; + DCHECK(slot->type().type == PrimitiveType::TYPE_BIGINT); + DCHECK(!slot->is_nullable()); + + vectorized::ColumnPtr src_column_ptr = block->get_by_position(idx).column; + const auto& src_nullable_column = + assert_cast(*src_column_ptr); + auto src_nested_column_ptr = src_nullable_column.get_nested_column_ptr(); + const auto& null_map_data = src_nullable_column.get_null_map_data(); + auto dst_column = vectorized::ColumnInt64::create(); + vectorized::ColumnInt64::Container& dst_values = dst_column->get_data(); + dst_values.reserve(rows); + + size_t null_value_count = 0; + for (size_t i = 0; i < rows; i++) { + null_value_count += null_map_data[i]; + } + + std::vector> res; + RETURN_IF_ERROR(_auto_inc_id_buffer->sync_request_ids(null_value_count, &res)); + for (auto [start, length] : res) { + _auto_inc_id_allocator.insert_ids(start, length); + } + + for (size_t i = 0; i < rows; i++) { + dst_values.emplace_back((null_map_data[i] != 0) ? _auto_inc_id_allocator.next_id() + : src_nested_column_ptr->get_int(i)); + } + block->get_by_position(idx).column = std::move(dst_column); + block->get_by_position(idx).type = + vectorized::DataTypeFactory::instance().create_data_type(slot->type(), false); + return Status::OK(); +} + } // namespace stream_load } // namespace doris \ No newline at end of file diff --git a/be/src/vec/sink/vtablet_block_convertor.h b/be/src/vec/sink/vtablet_block_convertor.h index 751c969396..bfc7b3b5d9 100644 --- a/be/src/vec/sink/vtablet_block_convertor.h +++ b/be/src/vec/sink/vtablet_block_convertor.h @@ -20,16 +20,20 @@ #include // IWYU pragma: no_include + #include // IWYU pragma: keep #include #include "common/status.h" #include "runtime/decimalv2_value.h" +#include "runtime/descriptors.h" #include "runtime/types.h" #include "util/bitmap.h" #include "vec/columns/column.h" #include "vec/core/block.h" +#include "vec/data_types/data_type_factory.hpp" #include "vec/exprs/vexpr_fwd.h" +#include "vec/sink/autoinc_buffer.h" namespace doris { namespace stream_load { @@ -41,8 +45,8 @@ public: Status validate_and_convert_block(RuntimeState* state, vectorized::Block* input_block, std::shared_ptr& block, - vectorized::VExprContextSPtrs output_vexpr_ctxs, - bool& has_filtered_rows); + vectorized::VExprContextSPtrs output_vexpr_ctxs, size_t rows, + bool eos, bool& has_filtered_rows); const Bitmap& filter_bitmap() { return _filter_bitmap; } @@ -50,6 +54,10 @@ public: int64_t num_filtered_rows() const { return _num_filtered_rows; } + void init_autoinc_info(int64_t db_id, int64_t table_id, int batch_size); + + AutoIncIDAllocator& auto_inc_id_allocator() { return _auto_inc_id_allocator; } + private: template DecimalV2Value _get_decimalv2_min_or_max(const TypeDescriptor& type); @@ -73,6 +81,8 @@ private: // so here need to do the convert operation void _convert_to_dest_desc_block(vectorized::Block* block); + Status _fill_auto_inc_cols(vectorized::Block* block, size_t rows, bool eos); + TupleDescriptor* _output_tuple_desc = nullptr; std::map, DecimalV2Value> _max_decimalv2_val; @@ -89,6 +99,11 @@ private: int64_t _validate_data_ns = 0; int64_t _num_filtered_rows = 0; + + size_t _batch_size; + std::optional _auto_inc_col_idx; + AutoIncIDBuffer* _auto_inc_id_buffer; + AutoIncIDAllocator _auto_inc_id_allocator; }; } // namespace stream_load diff --git a/be/src/vec/sink/vtablet_sink.cpp b/be/src/vec/sink/vtablet_sink.cpp index 519597943a..8de88ee82a 100644 --- a/be/src/vec/sink/vtablet_sink.cpp +++ b/be/src/vec/sink/vtablet_sink.cpp @@ -986,6 +986,8 @@ Status VOlapTableSink::prepare(RuntimeState* state) { } _block_convertor = std::make_unique(_output_tuple_desc); + _block_convertor->init_autoinc_info(_schema->db_id(), _schema->table_id(), + _state->batch_size()); _output_row_desc = _pool->add(new RowDescriptor(_output_tuple_desc, false)); // add all counter @@ -1213,7 +1215,7 @@ Status VOlapTableSink::send(RuntimeState* state, vectorized::Block* input_block, std::shared_ptr block; bool has_filtered_rows = false; RETURN_IF_ERROR(_block_convertor->validate_and_convert_block( - state, input_block, block, _output_vexpr_ctxs, has_filtered_rows)); + state, input_block, block, _output_vexpr_ctxs, rows, eos, has_filtered_rows)); // clear and release the references of columns input_block->clear(); diff --git a/docs/en/docs/sql-manual/sql-reference/Data-Definition-Statements/Create/CREATE-TABLE.md b/docs/en/docs/sql-manual/sql-reference/Data-Definition-Statements/Create/CREATE-TABLE.md index 6d77325138..04f0100b26 100644 --- a/docs/en/docs/sql-manual/sql-reference/Data-Definition-Statements/Create/CREATE-TABLE.md +++ b/docs/en/docs/sql-manual/sql-reference/Data-Definition-Statements/Create/CREATE-TABLE.md @@ -58,7 +58,7 @@ Column definition list: Column definition: - `column_name column_type [KEY] [aggr_type] [NULL] [default_value] [column_comment]` + `column_name column_type [KEY] [aggr_type] [NULL] [AUTO_INCREMENT] [default_value] [column_comment]` * `column_type` @@ -115,6 +115,12 @@ Column definition list: BITMAP_UNION: The aggregation mode of BIMTAP type columns, which performs the union aggregation of bitmaps. ``` + * `AUTO_INCREMENT`(only avaliable in master branch) + + To indicate if the column is a auto-increment column. Auto-increment column can be used to generate a unique identity for new row. If no values are assgined for auto-increment column when inserting, Doris will generate sequence numbers automatically. You can also assign the auto-increment column with NULL literal to indicate Doris to generate sequence numbers. It should be noted that, for performance reasons, BE will cache some values of auto-increment columns in memory. Therefore, the values generated by auto-increment columns can only guarantee monotonicity and uniqueness, but not strict continuity. + A table can have at most one auto-incremnt column. The auto-increment column should be BIGINT type and be NOT NULL. + Currently, only table of duplicate model supports auto-increment column. + * `default_value` Default value of the column. If the load data does not specify a value for this column, the system will assign a default value to this column. diff --git a/docs/zh-CN/docs/sql-manual/sql-reference/Data-Definition-Statements/Create/CREATE-TABLE.md b/docs/zh-CN/docs/sql-manual/sql-reference/Data-Definition-Statements/Create/CREATE-TABLE.md index 97e15be7bb..a0648af94d 100644 --- a/docs/zh-CN/docs/sql-manual/sql-reference/Data-Definition-Statements/Create/CREATE-TABLE.md +++ b/docs/zh-CN/docs/sql-manual/sql-reference/Data-Definition-Statements/Create/CREATE-TABLE.md @@ -56,7 +56,7 @@ distribution_desc * `column_definition` 列定义: - `column_name column_type [KEY] [aggr_type] [NULL] [default_value] [column_comment]` + `column_name column_type [KEY] [aggr_type] [NULL] [AUTO_INCREMENT] [default_value] [column_comment]` * `column_type` 列类型,支持以下类型: ``` @@ -106,7 +106,12 @@ distribution_desc HLL_UNION:HLL 类型的列的聚合方式,通过 HyperLogLog 算法聚合。 BITMAP_UNION:BIMTAP 类型的列的聚合方式,进行位图的并集聚合。 ``` - + * `AUTO_INCREMENT`(仅在master分支可用) + + 是否为自增列,自增列可以用来为新插入的行生成一个唯一标识。在插入表数据时如果没有指定自增列的值,则会自动生成一个合法的值。当自增列被显示地插入NULL时,其值也会被替换为生成的合法值。需要注意的是,处于性能考虑,BE会在内存中缓存部分自增列的值,所以自增列自动生成的值只能保证单调性和唯一性,无法保证严格的连续性。 + 一张表中至多有一个列是自增列,自增列必须是BIGINT类型,且必须为NOT NULL。 + 目前只有duplicate模型支持自增列。 + * `default_value` 列默认值,当导入数据未指定该列的值时,系统将赋予该列default_value。 diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/FeMetaVersion.java b/fe/fe-common/src/main/java/org/apache/doris/common/FeMetaVersion.java index b1e42d343a..1ae98bedcf 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/FeMetaVersion.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/FeMetaVersion.java @@ -66,9 +66,11 @@ public final class FeMetaVersion { public static final int VERSION_122 = 122; // For AnalysisInfo public static final int VERSION_123 = 123; + // For auto-increment column + public static final int VERSION_124 = 124; // note: when increment meta version, should assign the latest version to VERSION_CURRENT - public static final int VERSION_CURRENT = VERSION_123; + public static final int VERSION_CURRENT = VERSION_124; // all logs meta version should >= the minimum version, so that we could remove many if clause, for example // if (FE_METAVERSION < VERSION_94) ... diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java index 8323ff5cf7..50a75e68da 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/NativeInsertStmt.java @@ -383,6 +383,7 @@ public class NativeInsertStmt extends InsertStmt { slotDesc.setType(col.getType()); slotDesc.setColumn(col); slotDesc.setIsNullable(col.isAllowNull()); + slotDesc.setAutoInc(col.isAutoInc()); } } else if (targetTable instanceof MysqlTable || targetTable instanceof OdbcTable || targetTable instanceof JdbcTable) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java index e934ba45ac..919e285034 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java @@ -68,6 +68,7 @@ public class SlotDescriptor { // If set to false, then such slots will be ignored during // materialize them.Used to optimize to read less data and less memory usage private boolean needMaterialize = true; + private boolean isAutoInc = false; public SlotDescriptor(SlotId id, TupleDescriptor parent) { this.id = id; @@ -154,6 +155,14 @@ public class SlotDescriptor { isMaterialized = value; } + public boolean isAutoInc() { + return isAutoInc; + } + + public void setAutoInc(boolean isAutoInc) { + this.isAutoInc = isAutoInc; + } + public void materializeSrcExpr() { if (sourceExprs == null) { return; @@ -289,6 +298,7 @@ public class SlotDescriptor { byteOffset, 0, getIsNullable() ? 0 : -1, ((column != null) ? column.getName() : ""), slotIdx, isMaterialized); tSlotDescriptor.setNeedMaterialize(needMaterialize); + tSlotDescriptor.setIsAutoIncrement(isAutoInc); if (column != null) { LOG.debug("column name:{}, column unique id:{}", column.getName(), column.getUniqueId()); tSlotDescriptor.setColUniqueId(column.getUniqueId()); @@ -303,7 +313,8 @@ public class SlotDescriptor { String parentTupleId = (parent == null) ? "null" : parent.getId().toString(); return MoreObjects.toStringHelper(this).add("id", id.asInt()).add("parent", parentTupleId).add("col", colStr) .add("type", typeStr).add("materialized", isMaterialized).add("byteSize", byteSize) - .add("byteOffset", byteOffset).add("slotIdx", slotIdx).add("nullable", getIsNullable()).toString(); + .add("byteOffset", byteOffset).add("slotIdx", slotIdx).add("nullable", getIsNullable()) + .add("isAutoIncrement", isAutoInc).toString(); } @Override @@ -319,6 +330,7 @@ public class SlotDescriptor { .append(", colUniqueId=").append(column == null ? "null" : column.getUniqueId()) .append(", type=").append(type == null ? "null" : type.toSql()) .append(", nullable=").append(isNullable) + .append(", isAutoIncrement=").append(isAutoInc) .append("}") .toString(); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/AutoIncrementGenerator.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/AutoIncrementGenerator.java new file mode 100644 index 0000000000..ecda8fc9db --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/AutoIncrementGenerator.java @@ -0,0 +1,104 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.catalog; + +import org.apache.doris.common.Pair; +import org.apache.doris.common.UserException; +import org.apache.doris.common.io.Text; +import org.apache.doris.common.io.Writable; +import org.apache.doris.persist.AutoIncrementIdUpdateLog; +import org.apache.doris.persist.EditLog; +import org.apache.doris.persist.gson.GsonUtils; + +import com.google.common.base.Preconditions; +import com.google.gson.annotations.SerializedName; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class AutoIncrementGenerator implements Writable { + private static final Logger LOG = LogManager.getLogger(AutoIncrementGenerator.class); + + public static final long NEXT_ID_INIT_VALUE = 1; + // _MIN_BATCH_SIZE = 4064 in load task + private static final long BATCH_ID_INTERVAL = 50000; + + @SerializedName(value = "dbId") + private Long dbId; + @SerializedName(value = "tableId") + private Long tableId; + @SerializedName(value = "columnId") + private Long columnId; + @SerializedName(value = "nextId") + private long nextId; + @SerializedName(value = "batchEndId") + private long batchEndId; + + private EditLog editLog; + + public AutoIncrementGenerator() { + } + + public AutoIncrementGenerator(long dbId, long tableId, long columnId) { + this.dbId = dbId; + this.tableId = tableId; + this.columnId = columnId; + } + + public void setEditLog(EditLog editLog) { + this.editLog = editLog; + } + + public synchronized void applyChange(long columnId, long batchNextId) { + if (this.columnId == columnId && batchEndId < batchNextId) { + nextId = batchNextId; + batchEndId = batchNextId; + } + } + + public synchronized Pair getAutoIncrementRange(long columnId, + long length, long lowerBound) throws UserException { + LOG.info("[getAutoIncrementRange request][col:{}][length:{}], [{}]", columnId, length, this.columnId); + if (this.columnId != columnId) { + throw new UserException("column dosen't exist, columnId=" + columnId); + } + long startId = Math.max(nextId, lowerBound); + long endId = startId + length; + nextId = startId + length; + if (endId > batchEndId) { + batchEndId = (endId / BATCH_ID_INTERVAL + 1) * BATCH_ID_INTERVAL; + Preconditions.checkState(editLog != null); + AutoIncrementIdUpdateLog info = new AutoIncrementIdUpdateLog(dbId, tableId, columnId, batchEndId); + editLog.logUpdateAutoIncrementId(info); + } + LOG.info("[getAutoIncrementRange result][{}, {}]", startId, length); + return Pair.of(startId, length); + } + + @Override + public void write(DataOutput out) throws IOException { + Text.writeString(out, GsonUtils.GSON.toJson(this)); + } + + public static AutoIncrementGenerator read(DataInput in) throws IOException { + return GsonUtils.GSON.fromJson(Text.readString(in), AutoIncrementGenerator.class); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java index bfb26aad40..a62ac5a482 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java @@ -508,6 +508,7 @@ public class Column implements Writable, GsonPostProcessable { tColumn.setIsKey(this.isKey); tColumn.setIsAllowNull(this.isAllowNull); + tColumn.setIsAutoIncrement(this.isAutoInc); // keep compatibility tColumn.setDefaultValue(this.realDefaultValue == null ? this.defaultValue : this.realDefaultValue); tColumn.setVisible(visible); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java index 52ecb88ea0..8434270fcf 100755 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java @@ -171,6 +171,7 @@ import org.apache.doris.mysql.privilege.AccessControllerManager; import org.apache.doris.mysql.privilege.Auth; import org.apache.doris.mysql.privilege.PrivPredicate; import org.apache.doris.persist.AlterMultiMaterializedView; +import org.apache.doris.persist.AutoIncrementIdUpdateLog; import org.apache.doris.persist.BackendReplicasInfo; import org.apache.doris.persist.BackendTabletsInfo; import org.apache.doris.persist.BinlogGcInfo; @@ -5367,4 +5368,8 @@ public class Env { queryStats.clear(info); editLog.logCleanQueryStats(info); } + + public void replayAutoIncrementIdUpdateLog(AutoIncrementIdUpdateLog log) throws Exception { + getInternalCatalog().replayAutoIncrementIdUpdateLog(log); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java index 19a186607f..086c4bb7ec 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java @@ -40,6 +40,7 @@ import org.apache.doris.common.AnalysisException; import org.apache.doris.common.Config; import org.apache.doris.common.DdlException; import org.apache.doris.common.FeConstants; +import org.apache.doris.common.FeMetaVersion; import org.apache.doris.common.Pair; import org.apache.doris.common.UserException; import org.apache.doris.common.io.DeepCopy; @@ -151,6 +152,8 @@ public class OlapTable extends Table { private TableProperty tableProperty; + private AutoIncrementGenerator autoIncrementGenerator; + public OlapTable() { // for persist super(TableType.OLAP); @@ -1265,6 +1268,14 @@ public class OlapTable extends Table { tableProperty.write(out); } + // autoIncrementGenerator + if (autoIncrementGenerator == null) { + out.writeBoolean(false); + } else { + out.writeBoolean(true); + autoIncrementGenerator.write(out); + } + tempPartitions.write(out); } @@ -1345,6 +1356,15 @@ public class OlapTable extends Table { if (in.readBoolean()) { tableProperty = TableProperty.read(in); } + + if (Env.getCurrentEnvJournalVersion() >= FeMetaVersion.VERSION_124) { + // autoIncrementGenerator + if (in.readBoolean()) { + autoIncrementGenerator = AutoIncrementGenerator.read(in); + autoIncrementGenerator.setEditLog(Env.getCurrentEnv().getEditLog()); + } + } + if (isAutoBucket()) { defaultDistributionInfo.markAutoBucket(); } @@ -2109,4 +2129,18 @@ public class OlapTable extends Table { || (getKeysType() == KeysType.UNIQUE_KEYS && getEnableUniqueKeyMergeOnWrite()); } + + public void initAutoIncrentGenerator(long dbId) { + for (Column column : fullSchema) { + if (column.isAutoInc()) { + autoIncrementGenerator = new AutoIncrementGenerator(dbId, id, column.getUniqueId()); + autoIncrementGenerator.setEditLog(Env.getCurrentEnv().getEditLog()); + break; + } + } + } + + public AutoIncrementGenerator getAutoIncrementGenerator() { + return autoIncrementGenerator; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java index 16d6b46d50..8e996a110b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java @@ -136,6 +136,7 @@ import org.apache.doris.external.iceberg.IcebergTableCreationRecordMgr; import org.apache.doris.mtmv.MTMVJobFactory; import org.apache.doris.mtmv.metadata.MTMVJob; import org.apache.doris.persist.AlterDatabasePropertyInfo; +import org.apache.doris.persist.AutoIncrementIdUpdateLog; import org.apache.doris.persist.ColocatePersistInfo; import org.apache.doris.persist.DatabaseInfo; import org.apache.doris.persist.DropDbInfo; @@ -2230,6 +2231,7 @@ public class InternalCatalog implements CatalogIf { } olapTable.initSchemaColumnUniqueId(); + olapTable.initAutoIncrentGenerator(db.getId()); olapTable.rebuildFullSchema(); // analyze version info @@ -2965,4 +2967,10 @@ public class InternalCatalog implements CatalogIf { public Collection getAllDbs() { return new HashSet<>(idToDb.values()); } + + public void replayAutoIncrementIdUpdateLog(AutoIncrementIdUpdateLog log) throws MetaNotFoundException { + Database db = getDbOrMetaException(log.getDbId()); + OlapTable olapTable = (OlapTable) db.getTableOrMetaException(log.getTableId(), TableType.OLAP); + olapTable.getAutoIncrementGenerator().applyChange(log.getColumnId(), log.getBatchEndId()); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/journal/JournalEntity.java b/fe/fe-core/src/main/java/org/apache/doris/journal/JournalEntity.java index 2a29b18c85..5f87e553ef 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/journal/JournalEntity.java +++ b/fe/fe-core/src/main/java/org/apache/doris/journal/JournalEntity.java @@ -67,6 +67,7 @@ import org.apache.doris.persist.AlterRoutineLoadJobOperationLog; import org.apache.doris.persist.AlterUserOperationLog; import org.apache.doris.persist.AlterViewInfo; import org.apache.doris.persist.AnalyzeDeletionLog; +import org.apache.doris.persist.AutoIncrementIdUpdateLog; import org.apache.doris.persist.BackendReplicasInfo; import org.apache.doris.persist.BackendTabletsInfo; import org.apache.doris.persist.BarrierLog; @@ -817,6 +818,10 @@ public class JournalEntity implements Writable { } case OperationType.OP_DELETE_ANALYSIS_TASK: { data = AnalyzeDeletionLog.read(in); + break; + } + case OperationType.OP_UPDATE_AUTO_INCREMENT_ID: { + data = AutoIncrementIdUpdateLog.read(in); isRead = true; break; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/load/Load.java b/fe/fe-core/src/main/java/org/apache/doris/load/Load.java index a1aab0e075..590c02fb3a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/load/Load.java +++ b/fe/fe-core/src/main/java/org/apache/doris/load/Load.java @@ -562,7 +562,7 @@ public class Load { /* * This function will do followings: * 1. fill the column exprs if user does not specify any column or column mapping. - * 2. For not specified columns, check if they have default value. + * 2. For not specified columns, check if they have default value or they are auto-increment columns. * 3. Add any shadow columns if have. * 4. validate hadoop functions * 5. init slot descs and expr map for load plan @@ -629,7 +629,7 @@ public class Load { columnExprMap.put(importColumnDesc.getColumnName(), importColumnDesc.getExpr()); } - // check default value + // check default value and auto-increment column for (Column column : tbl.getBaseSchema()) { String columnName = column.getName(); if (columnExprMap.containsKey(columnName)) { @@ -638,7 +638,9 @@ public class Load { if (column.getDefaultValue() != null || column.isAllowNull() || isPartialUpdate) { continue; } - //continue; + if (column.isAutoInc()) { + continue; + } throw new DdlException("Column has no default value. column: " + columnName); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/persist/AutoIncrementIdUpdateLog.java b/fe/fe-core/src/main/java/org/apache/doris/persist/AutoIncrementIdUpdateLog.java new file mode 100644 index 0000000000..609206f194 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/persist/AutoIncrementIdUpdateLog.java @@ -0,0 +1,71 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.persist; + +import org.apache.doris.common.io.Text; +import org.apache.doris.common.io.Writable; +import org.apache.doris.persist.gson.GsonUtils; + +import com.google.gson.annotations.SerializedName; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class AutoIncrementIdUpdateLog implements Writable { + @SerializedName(value = "dbId") + private Long dbId; + @SerializedName(value = "tableId") + private Long tableId; + @SerializedName(value = "columnId") + private Long columnId; + @SerializedName(value = "batchEndId") + private Long batchEndId; + + public AutoIncrementIdUpdateLog(Long dbId, Long tableId, Long columnId, Long batchEndId) { + this.dbId = dbId; + this.tableId = tableId; + this.columnId = columnId; + this.batchEndId = batchEndId; + } + + public Long getDbId() { + return dbId; + } + + public Long getTableId() { + return tableId; + } + + public Long getColumnId() { + return columnId; + } + + public long getBatchEndId() { + return batchEndId; + } + + public static AutoIncrementIdUpdateLog read(DataInput in) throws IOException { + return GsonUtils.GSON.fromJson(Text.readString(in), AutoIncrementIdUpdateLog.class); + } + + @Override + public void write(DataOutput out) throws IOException { + Text.writeString(out, GsonUtils.GSON.toJson(this)); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/persist/EditLog.java b/fe/fe-core/src/main/java/org/apache/doris/persist/EditLog.java index f19d215e30..a6c7c9d91b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/persist/EditLog.java +++ b/fe/fe-core/src/main/java/org/apache/doris/persist/EditLog.java @@ -1052,6 +1052,10 @@ public class EditLog { LOG.info("replay barrier"); break; } + case OperationType.OP_UPDATE_AUTO_INCREMENT_ID: { + env.replayAutoIncrementIdUpdateLog((AutoIncrementIdUpdateLog) journal.getData()); + break; + } default: { IOException e = new IOException(); LOG.error("UNKNOWN Operation Type {}", opCode, e); @@ -1835,4 +1839,8 @@ public class EditLog { public long logBarrier() { return logEdit(OperationType.OP_BARRIER, new BarrierLog()); } + + public void logUpdateAutoIncrementId(AutoIncrementIdUpdateLog log) { + logEdit(OperationType.OP_UPDATE_AUTO_INCREMENT_ID, log); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/persist/OperationType.java b/fe/fe-core/src/main/java/org/apache/doris/persist/OperationType.java index 451a3eb7aa..2b935e74c5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/persist/OperationType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/persist/OperationType.java @@ -310,6 +310,8 @@ public class OperationType { public static final short OP_BARRIER = 436; + // change an auto increment id for a column + public static final short OP_UPDATE_AUTO_INCREMENT_ID = 437; /** * Get opcode name by op code. diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/FileLoadScanNode.java b/fe/fe-core/src/main/java/org/apache/doris/planner/FileLoadScanNode.java index c20a916bf9..b672b30930 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/FileLoadScanNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/FileLoadScanNode.java @@ -261,6 +261,11 @@ public class FileLoadScanNode extends FileScanNode { } else { if (column.isAllowNull()) { expr = NullLiteral.create(column.getType()); + } else if (column.isAutoInc()) { + // auto-increment column should be non-nullable + // however, here we use `NullLiteral` to indicate that a cell should + // be filled with generated value in `VOlapTableSink::_fill_auto_inc_cols()` + expr = NullLiteral.create(column.getType()); } else { throw new AnalysisException("column has no source field, column=" + column.getName()); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/StreamLoadPlanner.java b/fe/fe-core/src/main/java/org/apache/doris/planner/StreamLoadPlanner.java index b9014206dd..94bcf6ca79 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/StreamLoadPlanner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/StreamLoadPlanner.java @@ -176,10 +176,18 @@ public class StreamLoadPlanner { slotDesc.setIsMaterialized(true); slotDesc.setColumn(col); slotDesc.setIsNullable(col.isAllowNull()); + slotDesc.setAutoInc(col.isAutoInc()); SlotDescriptor scanSlotDesc = descTable.addSlotDescriptor(scanTupleDesc); scanSlotDesc.setIsMaterialized(true); scanSlotDesc.setColumn(col); scanSlotDesc.setIsNullable(col.isAllowNull()); + scanSlotDesc.setAutoInc(col.isAutoInc()); + if (col.isAutoInc()) { + // auto-increment column should be non-nullable + // however, here we use `NullLiteral` to indicate that a cell should + // be filled with generated value in `VOlapTableSink::_fill_auto_inc_cols()` + scanSlotDesc.setIsNullable(true); + } for (ImportColumnDesc importColumnDesc : taskInfo.getColumnExprDescs().descs) { try { if (!importColumnDesc.isColumn() && importColumnDesc.getColumnName() != null @@ -378,10 +386,18 @@ public class StreamLoadPlanner { slotDesc.setIsMaterialized(true); slotDesc.setColumn(col); slotDesc.setIsNullable(col.isAllowNull()); + slotDesc.setAutoInc(col.isAutoInc()); SlotDescriptor scanSlotDesc = descTable.addSlotDescriptor(scanTupleDesc); scanSlotDesc.setIsMaterialized(true); scanSlotDesc.setColumn(col); scanSlotDesc.setIsNullable(col.isAllowNull()); + scanSlotDesc.setAutoInc(col.isAutoInc()); + if (col.isAutoInc()) { + // auto-increment column should be non-nullable + // however, here we use `NullLiteral` to indicate that a cell should + // be filled with generated value in `VOlapTableSink::_fill_auto_inc_cols()` + scanSlotDesc.setIsNullable(true); + } for (ImportColumnDesc importColumnDesc : taskInfo.getColumnExprDescs().descs) { try { if (!importColumnDesc.isColumn() && importColumnDesc.getColumnName() != null diff --git a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java index 00dd9057af..faa79efbb8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java +++ b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java @@ -28,6 +28,7 @@ import org.apache.doris.analysis.TableName; import org.apache.doris.analysis.TypeDef; import org.apache.doris.analysis.UserIdentity; import org.apache.doris.backup.Snapshot; +import org.apache.doris.catalog.AutoIncrementGenerator; import org.apache.doris.catalog.Column; import org.apache.doris.catalog.Database; import org.apache.doris.catalog.DatabaseIf; @@ -86,6 +87,8 @@ import org.apache.doris.thrift.FrontendService; import org.apache.doris.thrift.FrontendServiceVersion; import org.apache.doris.thrift.TAddColumnsRequest; import org.apache.doris.thrift.TAddColumnsResult; +import org.apache.doris.thrift.TAutoIncrementRangeRequest; +import org.apache.doris.thrift.TAutoIncrementRangeResult; import org.apache.doris.thrift.TBeginTxnRequest; import org.apache.doris.thrift.TBeginTxnResult; import org.apache.doris.thrift.TBinlog; @@ -2322,6 +2325,41 @@ public class FrontendServiceImpl implements FrontendService.Iface { return result; } + @Override + public TAutoIncrementRangeResult getAutoIncrementRange(TAutoIncrementRangeRequest request) { + String clientAddr = getClientAddrAsString(); + LOG.debug("receive get auto-increement range request: {}, backend: {}", request, clientAddr); + + TAutoIncrementRangeResult result = new TAutoIncrementRangeResult(); + TStatus status = new TStatus(TStatusCode.OK); + result.setStatus(status); + try { + Env env = Env.getCurrentEnv(); + Database db = env.getInternalCatalog().getDbOrMetaException(request.getDbId()); + OlapTable olapTable = (OlapTable) db.getTableOrMetaException(request.getTableId(), TableType.OLAP); + AutoIncrementGenerator autoIncrementGenerator = null; + autoIncrementGenerator = olapTable.getAutoIncrementGenerator(); + long columnId = request.getColumnId(); + long length = request.getLength(); + long lowerBound = -1; + if (request.isSetLowerBound()) { + lowerBound = request.getLowerBound(); + } + Pair range = autoIncrementGenerator.getAutoIncrementRange(columnId, length, lowerBound); + result.setStart(range.first); + result.setLength(range.second); + } catch (UserException e) { + LOG.warn("failed to get auto-increment range of column {}: {}", request.getColumnId(), e.getMessage()); + status.setStatusCode(TStatusCode.ANALYSIS_ERROR); + status.addToErrorMsgs(e.getMessage()); + } catch (Throwable e) { + LOG.warn("catch unknown result.", e); + status.setStatusCode(TStatusCode.INTERNAL_ERROR); + status.addToErrorMsgs(e.getClass().getSimpleName() + ": " + Strings.nullToEmpty(e.getMessage())); + } + return result; + } + public TGetBinlogResult getBinlog(TGetBinlogRequest request) throws TException { String clientAddr = getClientAddrAsString(); LOG.debug("receive get binlog request: {}", request); diff --git a/gensrc/proto/descriptors.proto b/gensrc/proto/descriptors.proto index 97c2e6d993..abebf8fde5 100644 --- a/gensrc/proto/descriptors.proto +++ b/gensrc/proto/descriptors.proto @@ -36,6 +36,7 @@ message PSlotDescriptor { optional bool is_materialized = 10; optional int32 col_unique_id = 11; optional bool is_key = 12; + optional bool is_auto_increment = 13; }; message PTupleDescriptor { diff --git a/gensrc/thrift/Descriptors.thrift b/gensrc/thrift/Descriptors.thrift index 40c89c6748..5ea3375db3 100644 --- a/gensrc/thrift/Descriptors.thrift +++ b/gensrc/thrift/Descriptors.thrift @@ -39,6 +39,7 @@ struct TColumn { 15: optional i32 gram_bf_size 16: optional string aggregation 17: optional bool result_is_nullable + 18: optional bool is_auto_increment = false; } struct TSlotDescriptor { @@ -57,6 +58,7 @@ struct TSlotDescriptor { // If set to false, then such slots will be ignored during // materialize them.Used to optmize to read less data and less memory usage 13: optional bool need_materialize = true + 14: optional bool is_auto_increment = false; } struct TTupleDescriptor { diff --git a/gensrc/thrift/FrontendService.thrift b/gensrc/thrift/FrontendService.thrift index 95c2a75fbb..06c3d96c72 100644 --- a/gensrc/thrift/FrontendService.thrift +++ b/gensrc/thrift/FrontendService.thrift @@ -1065,6 +1065,20 @@ struct TUpdateFollowerStatsCacheRequest { 2: optional string colStats; } +struct TAutoIncrementRangeRequest { + 1: optional i64 db_id; + 2: optional i64 table_id; + 3: optional i64 column_id; + 4: optional i64 length + 5: optional i64 lower_bound // if set, values in result range must larger than `lower_bound` +} + +struct TAutoIncrementRangeResult { + 1: optional Status.TStatus status + 2: optional i64 start + 3: optional i64 length +} + service FrontendService { TGetDbsResult getDbNames(1: TGetDbsParams params) TGetTablesResult getTableNames(1: TGetTablesParams params) @@ -1131,4 +1145,6 @@ service FrontendService { TGetBinlogLagResult getBinlogLag(1: TGetBinlogLagRequest request) Status.TStatus updateStatsCache(1: TUpdateFollowerStatsCacheRequest request) + + TAutoIncrementRangeResult getAutoIncrementRange(1: TAutoIncrementRangeRequest request) } diff --git a/regression-test/data/data_model_p0/duplicate/storage/auto_inc_10000.csv b/regression-test/data/data_model_p0/duplicate/storage/auto_inc_10000.csv new file mode 100644 index 0000000000..2f14a2ce4b --- /dev/null +++ b/regression-test/data/data_model_p0/duplicate/storage/auto_inc_10000.csv @@ -0,0 +1,10001 @@ +0,0 +1,2 +2,4 +3,6 +4,8 +5,10 +6,12 +7,14 +8,16 +9,18 +10,20 +11,22 +12,24 +13,26 +14,28 +15,30 +16,32 +17,34 +18,36 +19,38 +20,40 +21,42 +22,44 +23,46 +24,48 +25,50 +26,52 +27,54 +28,56 +29,58 +30,60 +31,62 +32,64 +33,66 +34,68 +35,70 +36,72 +37,74 +38,76 +39,78 +40,80 +41,82 +42,84 +43,86 +44,88 +45,90 +46,92 +47,94 +48,96 +49,98 +50,100 +51,102 +52,104 +53,106 +54,108 +55,110 +56,112 +57,114 +58,116 +59,118 +60,120 +61,122 +62,124 +63,126 +64,128 +65,130 +66,132 +67,134 +68,136 +69,138 +70,140 +71,142 +72,144 +73,146 +74,148 +75,150 +76,152 +77,154 +78,156 +79,158 +80,160 +81,162 +82,164 +83,166 +84,168 +85,170 +86,172 +87,174 +88,176 +89,178 +90,180 +91,182 +92,184 +93,186 +94,188 +95,190 +96,192 +97,194 +98,196 +99,198 +100,200 +101,202 +102,204 +103,206 +104,208 +105,210 +106,212 +107,214 +108,216 +109,218 +110,220 +111,222 +112,224 +113,226 +114,228 +115,230 +116,232 +117,234 +118,236 +119,238 +120,240 +121,242 +122,244 +123,246 +124,248 +125,250 +126,252 +127,254 +128,256 +129,258 +130,260 +131,262 +132,264 +133,266 +134,268 +135,270 +136,272 +137,274 +138,276 +139,278 +140,280 +141,282 +142,284 +143,286 +144,288 +145,290 +146,292 +147,294 +148,296 +149,298 +150,300 +151,302 +152,304 +153,306 +154,308 +155,310 +156,312 +157,314 +158,316 +159,318 +160,320 +161,322 +162,324 +163,326 +164,328 +165,330 +166,332 +167,334 +168,336 +169,338 +170,340 +171,342 +172,344 +173,346 +174,348 +175,350 +176,352 +177,354 +178,356 +179,358 +180,360 +181,362 +182,364 +183,366 +184,368 +185,370 +186,372 +187,374 +188,376 +189,378 +190,380 +191,382 +192,384 +193,386 +194,388 +195,390 +196,392 +197,394 +198,396 +199,398 +200,400 +201,402 +202,404 +203,406 +204,408 +205,410 +206,412 +207,414 +208,416 +209,418 +210,420 +211,422 +212,424 +213,426 +214,428 +215,430 +216,432 +217,434 +218,436 +219,438 +220,440 +221,442 +222,444 +223,446 +224,448 +225,450 +226,452 +227,454 +228,456 +229,458 +230,460 +231,462 +232,464 +233,466 +234,468 +235,470 +236,472 +237,474 +238,476 +239,478 +240,480 +241,482 +242,484 +243,486 +244,488 +245,490 +246,492 +247,494 +248,496 +249,498 +250,500 +251,502 +252,504 +253,506 +254,508 +255,510 +256,512 +257,514 +258,516 +259,518 +260,520 +261,522 +262,524 +263,526 +264,528 +265,530 +266,532 +267,534 +268,536 +269,538 +270,540 +271,542 +272,544 +273,546 +274,548 +275,550 +276,552 +277,554 +278,556 +279,558 +280,560 +281,562 +282,564 +283,566 +284,568 +285,570 +286,572 +287,574 +288,576 +289,578 +290,580 +291,582 +292,584 +293,586 +294,588 +295,590 +296,592 +297,594 +298,596 +299,598 +300,600 +301,602 +302,604 +303,606 +304,608 +305,610 +306,612 +307,614 +308,616 +309,618 +310,620 +311,622 +312,624 +313,626 +314,628 +315,630 +316,632 +317,634 +318,636 +319,638 +320,640 +321,642 +322,644 +323,646 +324,648 +325,650 +326,652 +327,654 +328,656 +329,658 +330,660 +331,662 +332,664 +333,666 +334,668 +335,670 +336,672 +337,674 +338,676 +339,678 +340,680 +341,682 +342,684 +343,686 +344,688 +345,690 +346,692 +347,694 +348,696 +349,698 +350,700 +351,702 +352,704 +353,706 +354,708 +355,710 +356,712 +357,714 +358,716 +359,718 +360,720 +361,722 +362,724 +363,726 +364,728 +365,730 +366,732 +367,734 +368,736 +369,738 +370,740 +371,742 +372,744 +373,746 +374,748 +375,750 +376,752 +377,754 +378,756 +379,758 +380,760 +381,762 +382,764 +383,766 +384,768 +385,770 +386,772 +387,774 +388,776 +389,778 +390,780 +391,782 +392,784 +393,786 +394,788 +395,790 +396,792 +397,794 +398,796 +399,798 +400,800 +401,802 +402,804 +403,806 +404,808 +405,810 +406,812 +407,814 +408,816 +409,818 +410,820 +411,822 +412,824 +413,826 +414,828 +415,830 +416,832 +417,834 +418,836 +419,838 +420,840 +421,842 +422,844 +423,846 +424,848 +425,850 +426,852 +427,854 +428,856 +429,858 +430,860 +431,862 +432,864 +433,866 +434,868 +435,870 +436,872 +437,874 +438,876 +439,878 +440,880 +441,882 +442,884 +443,886 +444,888 +445,890 +446,892 +447,894 +448,896 +449,898 +450,900 +451,902 +452,904 +453,906 +454,908 +455,910 +456,912 +457,914 +458,916 +459,918 +460,920 +461,922 +462,924 +463,926 +464,928 +465,930 +466,932 +467,934 +468,936 +469,938 +470,940 +471,942 +472,944 +473,946 +474,948 +475,950 +476,952 +477,954 +478,956 +479,958 +480,960 +481,962 +482,964 +483,966 +484,968 +485,970 +486,972 +487,974 +488,976 +489,978 +490,980 +491,982 +492,984 +493,986 +494,988 +495,990 +496,992 +497,994 +498,996 +499,998 +500,1000 +501,1002 +502,1004 +503,1006 +504,1008 +505,1010 +506,1012 +507,1014 +508,1016 +509,1018 +510,1020 +511,1022 +512,1024 +513,1026 +514,1028 +515,1030 +516,1032 +517,1034 +518,1036 +519,1038 +520,1040 +521,1042 +522,1044 +523,1046 +524,1048 +525,1050 +526,1052 +527,1054 +528,1056 +529,1058 +530,1060 +531,1062 +532,1064 +533,1066 +534,1068 +535,1070 +536,1072 +537,1074 +538,1076 +539,1078 +540,1080 +541,1082 +542,1084 +543,1086 +544,1088 +545,1090 +546,1092 +547,1094 +548,1096 +549,1098 +550,1100 +551,1102 +552,1104 +553,1106 +554,1108 +555,1110 +556,1112 +557,1114 +558,1116 +559,1118 +560,1120 +561,1122 +562,1124 +563,1126 +564,1128 +565,1130 +566,1132 +567,1134 +568,1136 +569,1138 +570,1140 +571,1142 +572,1144 +573,1146 +574,1148 +575,1150 +576,1152 +577,1154 +578,1156 +579,1158 +580,1160 +581,1162 +582,1164 +583,1166 +584,1168 +585,1170 +586,1172 +587,1174 +588,1176 +589,1178 +590,1180 +591,1182 +592,1184 +593,1186 +594,1188 +595,1190 +596,1192 +597,1194 +598,1196 +599,1198 +600,1200 +601,1202 +602,1204 +603,1206 +604,1208 +605,1210 +606,1212 +607,1214 +608,1216 +609,1218 +610,1220 +611,1222 +612,1224 +613,1226 +614,1228 +615,1230 +616,1232 +617,1234 +618,1236 +619,1238 +620,1240 +621,1242 +622,1244 +623,1246 +624,1248 +625,1250 +626,1252 +627,1254 +628,1256 +629,1258 +630,1260 +631,1262 +632,1264 +633,1266 +634,1268 +635,1270 +636,1272 +637,1274 +638,1276 +639,1278 +640,1280 +641,1282 +642,1284 +643,1286 +644,1288 +645,1290 +646,1292 +647,1294 +648,1296 +649,1298 +650,1300 +651,1302 +652,1304 +653,1306 +654,1308 +655,1310 +656,1312 +657,1314 +658,1316 +659,1318 +660,1320 +661,1322 +662,1324 +663,1326 +664,1328 +665,1330 +666,1332 +667,1334 +668,1336 +669,1338 +670,1340 +671,1342 +672,1344 +673,1346 +674,1348 +675,1350 +676,1352 +677,1354 +678,1356 +679,1358 +680,1360 +681,1362 +682,1364 +683,1366 +684,1368 +685,1370 +686,1372 +687,1374 +688,1376 +689,1378 +690,1380 +691,1382 +692,1384 +693,1386 +694,1388 +695,1390 +696,1392 +697,1394 +698,1396 +699,1398 +700,1400 +701,1402 +702,1404 +703,1406 +704,1408 +705,1410 +706,1412 +707,1414 +708,1416 +709,1418 +710,1420 +711,1422 +712,1424 +713,1426 +714,1428 +715,1430 +716,1432 +717,1434 +718,1436 +719,1438 +720,1440 +721,1442 +722,1444 +723,1446 +724,1448 +725,1450 +726,1452 +727,1454 +728,1456 +729,1458 +730,1460 +731,1462 +732,1464 +733,1466 +734,1468 +735,1470 +736,1472 +737,1474 +738,1476 +739,1478 +740,1480 +741,1482 +742,1484 +743,1486 +744,1488 +745,1490 +746,1492 +747,1494 +748,1496 +749,1498 +750,1500 +751,1502 +752,1504 +753,1506 +754,1508 +755,1510 +756,1512 +757,1514 +758,1516 +759,1518 +760,1520 +761,1522 +762,1524 +763,1526 +764,1528 +765,1530 +766,1532 +767,1534 +768,1536 +769,1538 +770,1540 +771,1542 +772,1544 +773,1546 +774,1548 +775,1550 +776,1552 +777,1554 +778,1556 +779,1558 +780,1560 +781,1562 +782,1564 +783,1566 +784,1568 +785,1570 +786,1572 +787,1574 +788,1576 +789,1578 +790,1580 +791,1582 +792,1584 +793,1586 +794,1588 +795,1590 +796,1592 +797,1594 +798,1596 +799,1598 +800,1600 +801,1602 +802,1604 +803,1606 +804,1608 +805,1610 +806,1612 +807,1614 +808,1616 +809,1618 +810,1620 +811,1622 +812,1624 +813,1626 +814,1628 +815,1630 +816,1632 +817,1634 +818,1636 +819,1638 +820,1640 +821,1642 +822,1644 +823,1646 +824,1648 +825,1650 +826,1652 +827,1654 +828,1656 +829,1658 +830,1660 +831,1662 +832,1664 +833,1666 +834,1668 +835,1670 +836,1672 +837,1674 +838,1676 +839,1678 +840,1680 +841,1682 +842,1684 +843,1686 +844,1688 +845,1690 +846,1692 +847,1694 +848,1696 +849,1698 +850,1700 +851,1702 +852,1704 +853,1706 +854,1708 +855,1710 +856,1712 +857,1714 +858,1716 +859,1718 +860,1720 +861,1722 +862,1724 +863,1726 +864,1728 +865,1730 +866,1732 +867,1734 +868,1736 +869,1738 +870,1740 +871,1742 +872,1744 +873,1746 +874,1748 +875,1750 +876,1752 +877,1754 +878,1756 +879,1758 +880,1760 +881,1762 +882,1764 +883,1766 +884,1768 +885,1770 +886,1772 +887,1774 +888,1776 +889,1778 +890,1780 +891,1782 +892,1784 +893,1786 +894,1788 +895,1790 +896,1792 +897,1794 +898,1796 +899,1798 +900,1800 +901,1802 +902,1804 +903,1806 +904,1808 +905,1810 +906,1812 +907,1814 +908,1816 +909,1818 +910,1820 +911,1822 +912,1824 +913,1826 +914,1828 +915,1830 +916,1832 +917,1834 +918,1836 +919,1838 +920,1840 +921,1842 +922,1844 +923,1846 +924,1848 +925,1850 +926,1852 +927,1854 +928,1856 +929,1858 +930,1860 +931,1862 +932,1864 +933,1866 +934,1868 +935,1870 +936,1872 +937,1874 +938,1876 +939,1878 +940,1880 +941,1882 +942,1884 +943,1886 +944,1888 +945,1890 +946,1892 +947,1894 +948,1896 +949,1898 +950,1900 +951,1902 +952,1904 +953,1906 +954,1908 +955,1910 +956,1912 +957,1914 +958,1916 +959,1918 +960,1920 +961,1922 +962,1924 +963,1926 +964,1928 +965,1930 +966,1932 +967,1934 +968,1936 +969,1938 +970,1940 +971,1942 +972,1944 +973,1946 +974,1948 +975,1950 +976,1952 +977,1954 +978,1956 +979,1958 +980,1960 +981,1962 +982,1964 +983,1966 +984,1968 +985,1970 +986,1972 +987,1974 +988,1976 +989,1978 +990,1980 +991,1982 +992,1984 +993,1986 +994,1988 +995,1990 +996,1992 +997,1994 +998,1996 +999,1998 +1000,2000 +1001,2002 +1002,2004 +1003,2006 +1004,2008 +1005,2010 +1006,2012 +1007,2014 +1008,2016 +1009,2018 +1010,2020 +1011,2022 +1012,2024 +1013,2026 +1014,2028 +1015,2030 +1016,2032 +1017,2034 +1018,2036 +1019,2038 +1020,2040 +1021,2042 +1022,2044 +1023,2046 +1024,2048 +1025,2050 +1026,2052 +1027,2054 +1028,2056 +1029,2058 +1030,2060 +1031,2062 +1032,2064 +1033,2066 +1034,2068 +1035,2070 +1036,2072 +1037,2074 +1038,2076 +1039,2078 +1040,2080 +1041,2082 +1042,2084 +1043,2086 +1044,2088 +1045,2090 +1046,2092 +1047,2094 +1048,2096 +1049,2098 +1050,2100 +1051,2102 +1052,2104 +1053,2106 +1054,2108 +1055,2110 +1056,2112 +1057,2114 +1058,2116 +1059,2118 +1060,2120 +1061,2122 +1062,2124 +1063,2126 +1064,2128 +1065,2130 +1066,2132 +1067,2134 +1068,2136 +1069,2138 +1070,2140 +1071,2142 +1072,2144 +1073,2146 +1074,2148 +1075,2150 +1076,2152 +1077,2154 +1078,2156 +1079,2158 +1080,2160 +1081,2162 +1082,2164 +1083,2166 +1084,2168 +1085,2170 +1086,2172 +1087,2174 +1088,2176 +1089,2178 +1090,2180 +1091,2182 +1092,2184 +1093,2186 +1094,2188 +1095,2190 +1096,2192 +1097,2194 +1098,2196 +1099,2198 +1100,2200 +1101,2202 +1102,2204 +1103,2206 +1104,2208 +1105,2210 +1106,2212 +1107,2214 +1108,2216 +1109,2218 +1110,2220 +1111,2222 +1112,2224 +1113,2226 +1114,2228 +1115,2230 +1116,2232 +1117,2234 +1118,2236 +1119,2238 +1120,2240 +1121,2242 +1122,2244 +1123,2246 +1124,2248 +1125,2250 +1126,2252 +1127,2254 +1128,2256 +1129,2258 +1130,2260 +1131,2262 +1132,2264 +1133,2266 +1134,2268 +1135,2270 +1136,2272 +1137,2274 +1138,2276 +1139,2278 +1140,2280 +1141,2282 +1142,2284 +1143,2286 +1144,2288 +1145,2290 +1146,2292 +1147,2294 +1148,2296 +1149,2298 +1150,2300 +1151,2302 +1152,2304 +1153,2306 +1154,2308 +1155,2310 +1156,2312 +1157,2314 +1158,2316 +1159,2318 +1160,2320 +1161,2322 +1162,2324 +1163,2326 +1164,2328 +1165,2330 +1166,2332 +1167,2334 +1168,2336 +1169,2338 +1170,2340 +1171,2342 +1172,2344 +1173,2346 +1174,2348 +1175,2350 +1176,2352 +1177,2354 +1178,2356 +1179,2358 +1180,2360 +1181,2362 +1182,2364 +1183,2366 +1184,2368 +1185,2370 +1186,2372 +1187,2374 +1188,2376 +1189,2378 +1190,2380 +1191,2382 +1192,2384 +1193,2386 +1194,2388 +1195,2390 +1196,2392 +1197,2394 +1198,2396 +1199,2398 +1200,2400 +1201,2402 +1202,2404 +1203,2406 +1204,2408 +1205,2410 +1206,2412 +1207,2414 +1208,2416 +1209,2418 +1210,2420 +1211,2422 +1212,2424 +1213,2426 +1214,2428 +1215,2430 +1216,2432 +1217,2434 +1218,2436 +1219,2438 +1220,2440 +1221,2442 +1222,2444 +1223,2446 +1224,2448 +1225,2450 +1226,2452 +1227,2454 +1228,2456 +1229,2458 +1230,2460 +1231,2462 +1232,2464 +1233,2466 +1234,2468 +1235,2470 +1236,2472 +1237,2474 +1238,2476 +1239,2478 +1240,2480 +1241,2482 +1242,2484 +1243,2486 +1244,2488 +1245,2490 +1246,2492 +1247,2494 +1248,2496 +1249,2498 +1250,2500 +1251,2502 +1252,2504 +1253,2506 +1254,2508 +1255,2510 +1256,2512 +1257,2514 +1258,2516 +1259,2518 +1260,2520 +1261,2522 +1262,2524 +1263,2526 +1264,2528 +1265,2530 +1266,2532 +1267,2534 +1268,2536 +1269,2538 +1270,2540 +1271,2542 +1272,2544 +1273,2546 +1274,2548 +1275,2550 +1276,2552 +1277,2554 +1278,2556 +1279,2558 +1280,2560 +1281,2562 +1282,2564 +1283,2566 +1284,2568 +1285,2570 +1286,2572 +1287,2574 +1288,2576 +1289,2578 +1290,2580 +1291,2582 +1292,2584 +1293,2586 +1294,2588 +1295,2590 +1296,2592 +1297,2594 +1298,2596 +1299,2598 +1300,2600 +1301,2602 +1302,2604 +1303,2606 +1304,2608 +1305,2610 +1306,2612 +1307,2614 +1308,2616 +1309,2618 +1310,2620 +1311,2622 +1312,2624 +1313,2626 +1314,2628 +1315,2630 +1316,2632 +1317,2634 +1318,2636 +1319,2638 +1320,2640 +1321,2642 +1322,2644 +1323,2646 +1324,2648 +1325,2650 +1326,2652 +1327,2654 +1328,2656 +1329,2658 +1330,2660 +1331,2662 +1332,2664 +1333,2666 +1334,2668 +1335,2670 +1336,2672 +1337,2674 +1338,2676 +1339,2678 +1340,2680 +1341,2682 +1342,2684 +1343,2686 +1344,2688 +1345,2690 +1346,2692 +1347,2694 +1348,2696 +1349,2698 +1350,2700 +1351,2702 +1352,2704 +1353,2706 +1354,2708 +1355,2710 +1356,2712 +1357,2714 +1358,2716 +1359,2718 +1360,2720 +1361,2722 +1362,2724 +1363,2726 +1364,2728 +1365,2730 +1366,2732 +1367,2734 +1368,2736 +1369,2738 +1370,2740 +1371,2742 +1372,2744 +1373,2746 +1374,2748 +1375,2750 +1376,2752 +1377,2754 +1378,2756 +1379,2758 +1380,2760 +1381,2762 +1382,2764 +1383,2766 +1384,2768 +1385,2770 +1386,2772 +1387,2774 +1388,2776 +1389,2778 +1390,2780 +1391,2782 +1392,2784 +1393,2786 +1394,2788 +1395,2790 +1396,2792 +1397,2794 +1398,2796 +1399,2798 +1400,2800 +1401,2802 +1402,2804 +1403,2806 +1404,2808 +1405,2810 +1406,2812 +1407,2814 +1408,2816 +1409,2818 +1410,2820 +1411,2822 +1412,2824 +1413,2826 +1414,2828 +1415,2830 +1416,2832 +1417,2834 +1418,2836 +1419,2838 +1420,2840 +1421,2842 +1422,2844 +1423,2846 +1424,2848 +1425,2850 +1426,2852 +1427,2854 +1428,2856 +1429,2858 +1430,2860 +1431,2862 +1432,2864 +1433,2866 +1434,2868 +1435,2870 +1436,2872 +1437,2874 +1438,2876 +1439,2878 +1440,2880 +1441,2882 +1442,2884 +1443,2886 +1444,2888 +1445,2890 +1446,2892 +1447,2894 +1448,2896 +1449,2898 +1450,2900 +1451,2902 +1452,2904 +1453,2906 +1454,2908 +1455,2910 +1456,2912 +1457,2914 +1458,2916 +1459,2918 +1460,2920 +1461,2922 +1462,2924 +1463,2926 +1464,2928 +1465,2930 +1466,2932 +1467,2934 +1468,2936 +1469,2938 +1470,2940 +1471,2942 +1472,2944 +1473,2946 +1474,2948 +1475,2950 +1476,2952 +1477,2954 +1478,2956 +1479,2958 +1480,2960 +1481,2962 +1482,2964 +1483,2966 +1484,2968 +1485,2970 +1486,2972 +1487,2974 +1488,2976 +1489,2978 +1490,2980 +1491,2982 +1492,2984 +1493,2986 +1494,2988 +1495,2990 +1496,2992 +1497,2994 +1498,2996 +1499,2998 +1500,3000 +1501,3002 +1502,3004 +1503,3006 +1504,3008 +1505,3010 +1506,3012 +1507,3014 +1508,3016 +1509,3018 +1510,3020 +1511,3022 +1512,3024 +1513,3026 +1514,3028 +1515,3030 +1516,3032 +1517,3034 +1518,3036 +1519,3038 +1520,3040 +1521,3042 +1522,3044 +1523,3046 +1524,3048 +1525,3050 +1526,3052 +1527,3054 +1528,3056 +1529,3058 +1530,3060 +1531,3062 +1532,3064 +1533,3066 +1534,3068 +1535,3070 +1536,3072 +1537,3074 +1538,3076 +1539,3078 +1540,3080 +1541,3082 +1542,3084 +1543,3086 +1544,3088 +1545,3090 +1546,3092 +1547,3094 +1548,3096 +1549,3098 +1550,3100 +1551,3102 +1552,3104 +1553,3106 +1554,3108 +1555,3110 +1556,3112 +1557,3114 +1558,3116 +1559,3118 +1560,3120 +1561,3122 +1562,3124 +1563,3126 +1564,3128 +1565,3130 +1566,3132 +1567,3134 +1568,3136 +1569,3138 +1570,3140 +1571,3142 +1572,3144 +1573,3146 +1574,3148 +1575,3150 +1576,3152 +1577,3154 +1578,3156 +1579,3158 +1580,3160 +1581,3162 +1582,3164 +1583,3166 +1584,3168 +1585,3170 +1586,3172 +1587,3174 +1588,3176 +1589,3178 +1590,3180 +1591,3182 +1592,3184 +1593,3186 +1594,3188 +1595,3190 +1596,3192 +1597,3194 +1598,3196 +1599,3198 +1600,3200 +1601,3202 +1602,3204 +1603,3206 +1604,3208 +1605,3210 +1606,3212 +1607,3214 +1608,3216 +1609,3218 +1610,3220 +1611,3222 +1612,3224 +1613,3226 +1614,3228 +1615,3230 +1616,3232 +1617,3234 +1618,3236 +1619,3238 +1620,3240 +1621,3242 +1622,3244 +1623,3246 +1624,3248 +1625,3250 +1626,3252 +1627,3254 +1628,3256 +1629,3258 +1630,3260 +1631,3262 +1632,3264 +1633,3266 +1634,3268 +1635,3270 +1636,3272 +1637,3274 +1638,3276 +1639,3278 +1640,3280 +1641,3282 +1642,3284 +1643,3286 +1644,3288 +1645,3290 +1646,3292 +1647,3294 +1648,3296 +1649,3298 +1650,3300 +1651,3302 +1652,3304 +1653,3306 +1654,3308 +1655,3310 +1656,3312 +1657,3314 +1658,3316 +1659,3318 +1660,3320 +1661,3322 +1662,3324 +1663,3326 +1664,3328 +1665,3330 +1666,3332 +1667,3334 +1668,3336 +1669,3338 +1670,3340 +1671,3342 +1672,3344 +1673,3346 +1674,3348 +1675,3350 +1676,3352 +1677,3354 +1678,3356 +1679,3358 +1680,3360 +1681,3362 +1682,3364 +1683,3366 +1684,3368 +1685,3370 +1686,3372 +1687,3374 +1688,3376 +1689,3378 +1690,3380 +1691,3382 +1692,3384 +1693,3386 +1694,3388 +1695,3390 +1696,3392 +1697,3394 +1698,3396 +1699,3398 +1700,3400 +1701,3402 +1702,3404 +1703,3406 +1704,3408 +1705,3410 +1706,3412 +1707,3414 +1708,3416 +1709,3418 +1710,3420 +1711,3422 +1712,3424 +1713,3426 +1714,3428 +1715,3430 +1716,3432 +1717,3434 +1718,3436 +1719,3438 +1720,3440 +1721,3442 +1722,3444 +1723,3446 +1724,3448 +1725,3450 +1726,3452 +1727,3454 +1728,3456 +1729,3458 +1730,3460 +1731,3462 +1732,3464 +1733,3466 +1734,3468 +1735,3470 +1736,3472 +1737,3474 +1738,3476 +1739,3478 +1740,3480 +1741,3482 +1742,3484 +1743,3486 +1744,3488 +1745,3490 +1746,3492 +1747,3494 +1748,3496 +1749,3498 +1750,3500 +1751,3502 +1752,3504 +1753,3506 +1754,3508 +1755,3510 +1756,3512 +1757,3514 +1758,3516 +1759,3518 +1760,3520 +1761,3522 +1762,3524 +1763,3526 +1764,3528 +1765,3530 +1766,3532 +1767,3534 +1768,3536 +1769,3538 +1770,3540 +1771,3542 +1772,3544 +1773,3546 +1774,3548 +1775,3550 +1776,3552 +1777,3554 +1778,3556 +1779,3558 +1780,3560 +1781,3562 +1782,3564 +1783,3566 +1784,3568 +1785,3570 +1786,3572 +1787,3574 +1788,3576 +1789,3578 +1790,3580 +1791,3582 +1792,3584 +1793,3586 +1794,3588 +1795,3590 +1796,3592 +1797,3594 +1798,3596 +1799,3598 +1800,3600 +1801,3602 +1802,3604 +1803,3606 +1804,3608 +1805,3610 +1806,3612 +1807,3614 +1808,3616 +1809,3618 +1810,3620 +1811,3622 +1812,3624 +1813,3626 +1814,3628 +1815,3630 +1816,3632 +1817,3634 +1818,3636 +1819,3638 +1820,3640 +1821,3642 +1822,3644 +1823,3646 +1824,3648 +1825,3650 +1826,3652 +1827,3654 +1828,3656 +1829,3658 +1830,3660 +1831,3662 +1832,3664 +1833,3666 +1834,3668 +1835,3670 +1836,3672 +1837,3674 +1838,3676 +1839,3678 +1840,3680 +1841,3682 +1842,3684 +1843,3686 +1844,3688 +1845,3690 +1846,3692 +1847,3694 +1848,3696 +1849,3698 +1850,3700 +1851,3702 +1852,3704 +1853,3706 +1854,3708 +1855,3710 +1856,3712 +1857,3714 +1858,3716 +1859,3718 +1860,3720 +1861,3722 +1862,3724 +1863,3726 +1864,3728 +1865,3730 +1866,3732 +1867,3734 +1868,3736 +1869,3738 +1870,3740 +1871,3742 +1872,3744 +1873,3746 +1874,3748 +1875,3750 +1876,3752 +1877,3754 +1878,3756 +1879,3758 +1880,3760 +1881,3762 +1882,3764 +1883,3766 +1884,3768 +1885,3770 +1886,3772 +1887,3774 +1888,3776 +1889,3778 +1890,3780 +1891,3782 +1892,3784 +1893,3786 +1894,3788 +1895,3790 +1896,3792 +1897,3794 +1898,3796 +1899,3798 +1900,3800 +1901,3802 +1902,3804 +1903,3806 +1904,3808 +1905,3810 +1906,3812 +1907,3814 +1908,3816 +1909,3818 +1910,3820 +1911,3822 +1912,3824 +1913,3826 +1914,3828 +1915,3830 +1916,3832 +1917,3834 +1918,3836 +1919,3838 +1920,3840 +1921,3842 +1922,3844 +1923,3846 +1924,3848 +1925,3850 +1926,3852 +1927,3854 +1928,3856 +1929,3858 +1930,3860 +1931,3862 +1932,3864 +1933,3866 +1934,3868 +1935,3870 +1936,3872 +1937,3874 +1938,3876 +1939,3878 +1940,3880 +1941,3882 +1942,3884 +1943,3886 +1944,3888 +1945,3890 +1946,3892 +1947,3894 +1948,3896 +1949,3898 +1950,3900 +1951,3902 +1952,3904 +1953,3906 +1954,3908 +1955,3910 +1956,3912 +1957,3914 +1958,3916 +1959,3918 +1960,3920 +1961,3922 +1962,3924 +1963,3926 +1964,3928 +1965,3930 +1966,3932 +1967,3934 +1968,3936 +1969,3938 +1970,3940 +1971,3942 +1972,3944 +1973,3946 +1974,3948 +1975,3950 +1976,3952 +1977,3954 +1978,3956 +1979,3958 +1980,3960 +1981,3962 +1982,3964 +1983,3966 +1984,3968 +1985,3970 +1986,3972 +1987,3974 +1988,3976 +1989,3978 +1990,3980 +1991,3982 +1992,3984 +1993,3986 +1994,3988 +1995,3990 +1996,3992 +1997,3994 +1998,3996 +1999,3998 +2000,4000 +2001,4002 +2002,4004 +2003,4006 +2004,4008 +2005,4010 +2006,4012 +2007,4014 +2008,4016 +2009,4018 +2010,4020 +2011,4022 +2012,4024 +2013,4026 +2014,4028 +2015,4030 +2016,4032 +2017,4034 +2018,4036 +2019,4038 +2020,4040 +2021,4042 +2022,4044 +2023,4046 +2024,4048 +2025,4050 +2026,4052 +2027,4054 +2028,4056 +2029,4058 +2030,4060 +2031,4062 +2032,4064 +2033,4066 +2034,4068 +2035,4070 +2036,4072 +2037,4074 +2038,4076 +2039,4078 +2040,4080 +2041,4082 +2042,4084 +2043,4086 +2044,4088 +2045,4090 +2046,4092 +2047,4094 +2048,4096 +2049,4098 +2050,4100 +2051,4102 +2052,4104 +2053,4106 +2054,4108 +2055,4110 +2056,4112 +2057,4114 +2058,4116 +2059,4118 +2060,4120 +2061,4122 +2062,4124 +2063,4126 +2064,4128 +2065,4130 +2066,4132 +2067,4134 +2068,4136 +2069,4138 +2070,4140 +2071,4142 +2072,4144 +2073,4146 +2074,4148 +2075,4150 +2076,4152 +2077,4154 +2078,4156 +2079,4158 +2080,4160 +2081,4162 +2082,4164 +2083,4166 +2084,4168 +2085,4170 +2086,4172 +2087,4174 +2088,4176 +2089,4178 +2090,4180 +2091,4182 +2092,4184 +2093,4186 +2094,4188 +2095,4190 +2096,4192 +2097,4194 +2098,4196 +2099,4198 +2100,4200 +2101,4202 +2102,4204 +2103,4206 +2104,4208 +2105,4210 +2106,4212 +2107,4214 +2108,4216 +2109,4218 +2110,4220 +2111,4222 +2112,4224 +2113,4226 +2114,4228 +2115,4230 +2116,4232 +2117,4234 +2118,4236 +2119,4238 +2120,4240 +2121,4242 +2122,4244 +2123,4246 +2124,4248 +2125,4250 +2126,4252 +2127,4254 +2128,4256 +2129,4258 +2130,4260 +2131,4262 +2132,4264 +2133,4266 +2134,4268 +2135,4270 +2136,4272 +2137,4274 +2138,4276 +2139,4278 +2140,4280 +2141,4282 +2142,4284 +2143,4286 +2144,4288 +2145,4290 +2146,4292 +2147,4294 +2148,4296 +2149,4298 +2150,4300 +2151,4302 +2152,4304 +2153,4306 +2154,4308 +2155,4310 +2156,4312 +2157,4314 +2158,4316 +2159,4318 +2160,4320 +2161,4322 +2162,4324 +2163,4326 +2164,4328 +2165,4330 +2166,4332 +2167,4334 +2168,4336 +2169,4338 +2170,4340 +2171,4342 +2172,4344 +2173,4346 +2174,4348 +2175,4350 +2176,4352 +2177,4354 +2178,4356 +2179,4358 +2180,4360 +2181,4362 +2182,4364 +2183,4366 +2184,4368 +2185,4370 +2186,4372 +2187,4374 +2188,4376 +2189,4378 +2190,4380 +2191,4382 +2192,4384 +2193,4386 +2194,4388 +2195,4390 +2196,4392 +2197,4394 +2198,4396 +2199,4398 +2200,4400 +2201,4402 +2202,4404 +2203,4406 +2204,4408 +2205,4410 +2206,4412 +2207,4414 +2208,4416 +2209,4418 +2210,4420 +2211,4422 +2212,4424 +2213,4426 +2214,4428 +2215,4430 +2216,4432 +2217,4434 +2218,4436 +2219,4438 +2220,4440 +2221,4442 +2222,4444 +2223,4446 +2224,4448 +2225,4450 +2226,4452 +2227,4454 +2228,4456 +2229,4458 +2230,4460 +2231,4462 +2232,4464 +2233,4466 +2234,4468 +2235,4470 +2236,4472 +2237,4474 +2238,4476 +2239,4478 +2240,4480 +2241,4482 +2242,4484 +2243,4486 +2244,4488 +2245,4490 +2246,4492 +2247,4494 +2248,4496 +2249,4498 +2250,4500 +2251,4502 +2252,4504 +2253,4506 +2254,4508 +2255,4510 +2256,4512 +2257,4514 +2258,4516 +2259,4518 +2260,4520 +2261,4522 +2262,4524 +2263,4526 +2264,4528 +2265,4530 +2266,4532 +2267,4534 +2268,4536 +2269,4538 +2270,4540 +2271,4542 +2272,4544 +2273,4546 +2274,4548 +2275,4550 +2276,4552 +2277,4554 +2278,4556 +2279,4558 +2280,4560 +2281,4562 +2282,4564 +2283,4566 +2284,4568 +2285,4570 +2286,4572 +2287,4574 +2288,4576 +2289,4578 +2290,4580 +2291,4582 +2292,4584 +2293,4586 +2294,4588 +2295,4590 +2296,4592 +2297,4594 +2298,4596 +2299,4598 +2300,4600 +2301,4602 +2302,4604 +2303,4606 +2304,4608 +2305,4610 +2306,4612 +2307,4614 +2308,4616 +2309,4618 +2310,4620 +2311,4622 +2312,4624 +2313,4626 +2314,4628 +2315,4630 +2316,4632 +2317,4634 +2318,4636 +2319,4638 +2320,4640 +2321,4642 +2322,4644 +2323,4646 +2324,4648 +2325,4650 +2326,4652 +2327,4654 +2328,4656 +2329,4658 +2330,4660 +2331,4662 +2332,4664 +2333,4666 +2334,4668 +2335,4670 +2336,4672 +2337,4674 +2338,4676 +2339,4678 +2340,4680 +2341,4682 +2342,4684 +2343,4686 +2344,4688 +2345,4690 +2346,4692 +2347,4694 +2348,4696 +2349,4698 +2350,4700 +2351,4702 +2352,4704 +2353,4706 +2354,4708 +2355,4710 +2356,4712 +2357,4714 +2358,4716 +2359,4718 +2360,4720 +2361,4722 +2362,4724 +2363,4726 +2364,4728 +2365,4730 +2366,4732 +2367,4734 +2368,4736 +2369,4738 +2370,4740 +2371,4742 +2372,4744 +2373,4746 +2374,4748 +2375,4750 +2376,4752 +2377,4754 +2378,4756 +2379,4758 +2380,4760 +2381,4762 +2382,4764 +2383,4766 +2384,4768 +2385,4770 +2386,4772 +2387,4774 +2388,4776 +2389,4778 +2390,4780 +2391,4782 +2392,4784 +2393,4786 +2394,4788 +2395,4790 +2396,4792 +2397,4794 +2398,4796 +2399,4798 +2400,4800 +2401,4802 +2402,4804 +2403,4806 +2404,4808 +2405,4810 +2406,4812 +2407,4814 +2408,4816 +2409,4818 +2410,4820 +2411,4822 +2412,4824 +2413,4826 +2414,4828 +2415,4830 +2416,4832 +2417,4834 +2418,4836 +2419,4838 +2420,4840 +2421,4842 +2422,4844 +2423,4846 +2424,4848 +2425,4850 +2426,4852 +2427,4854 +2428,4856 +2429,4858 +2430,4860 +2431,4862 +2432,4864 +2433,4866 +2434,4868 +2435,4870 +2436,4872 +2437,4874 +2438,4876 +2439,4878 +2440,4880 +2441,4882 +2442,4884 +2443,4886 +2444,4888 +2445,4890 +2446,4892 +2447,4894 +2448,4896 +2449,4898 +2450,4900 +2451,4902 +2452,4904 +2453,4906 +2454,4908 +2455,4910 +2456,4912 +2457,4914 +2458,4916 +2459,4918 +2460,4920 +2461,4922 +2462,4924 +2463,4926 +2464,4928 +2465,4930 +2466,4932 +2467,4934 +2468,4936 +2469,4938 +2470,4940 +2471,4942 +2472,4944 +2473,4946 +2474,4948 +2475,4950 +2476,4952 +2477,4954 +2478,4956 +2479,4958 +2480,4960 +2481,4962 +2482,4964 +2483,4966 +2484,4968 +2485,4970 +2486,4972 +2487,4974 +2488,4976 +2489,4978 +2490,4980 +2491,4982 +2492,4984 +2493,4986 +2494,4988 +2495,4990 +2496,4992 +2497,4994 +2498,4996 +2499,4998 +2500,5000 +2501,5002 +2502,5004 +2503,5006 +2504,5008 +2505,5010 +2506,5012 +2507,5014 +2508,5016 +2509,5018 +2510,5020 +2511,5022 +2512,5024 +2513,5026 +2514,5028 +2515,5030 +2516,5032 +2517,5034 +2518,5036 +2519,5038 +2520,5040 +2521,5042 +2522,5044 +2523,5046 +2524,5048 +2525,5050 +2526,5052 +2527,5054 +2528,5056 +2529,5058 +2530,5060 +2531,5062 +2532,5064 +2533,5066 +2534,5068 +2535,5070 +2536,5072 +2537,5074 +2538,5076 +2539,5078 +2540,5080 +2541,5082 +2542,5084 +2543,5086 +2544,5088 +2545,5090 +2546,5092 +2547,5094 +2548,5096 +2549,5098 +2550,5100 +2551,5102 +2552,5104 +2553,5106 +2554,5108 +2555,5110 +2556,5112 +2557,5114 +2558,5116 +2559,5118 +2560,5120 +2561,5122 +2562,5124 +2563,5126 +2564,5128 +2565,5130 +2566,5132 +2567,5134 +2568,5136 +2569,5138 +2570,5140 +2571,5142 +2572,5144 +2573,5146 +2574,5148 +2575,5150 +2576,5152 +2577,5154 +2578,5156 +2579,5158 +2580,5160 +2581,5162 +2582,5164 +2583,5166 +2584,5168 +2585,5170 +2586,5172 +2587,5174 +2588,5176 +2589,5178 +2590,5180 +2591,5182 +2592,5184 +2593,5186 +2594,5188 +2595,5190 +2596,5192 +2597,5194 +2598,5196 +2599,5198 +2600,5200 +2601,5202 +2602,5204 +2603,5206 +2604,5208 +2605,5210 +2606,5212 +2607,5214 +2608,5216 +2609,5218 +2610,5220 +2611,5222 +2612,5224 +2613,5226 +2614,5228 +2615,5230 +2616,5232 +2617,5234 +2618,5236 +2619,5238 +2620,5240 +2621,5242 +2622,5244 +2623,5246 +2624,5248 +2625,5250 +2626,5252 +2627,5254 +2628,5256 +2629,5258 +2630,5260 +2631,5262 +2632,5264 +2633,5266 +2634,5268 +2635,5270 +2636,5272 +2637,5274 +2638,5276 +2639,5278 +2640,5280 +2641,5282 +2642,5284 +2643,5286 +2644,5288 +2645,5290 +2646,5292 +2647,5294 +2648,5296 +2649,5298 +2650,5300 +2651,5302 +2652,5304 +2653,5306 +2654,5308 +2655,5310 +2656,5312 +2657,5314 +2658,5316 +2659,5318 +2660,5320 +2661,5322 +2662,5324 +2663,5326 +2664,5328 +2665,5330 +2666,5332 +2667,5334 +2668,5336 +2669,5338 +2670,5340 +2671,5342 +2672,5344 +2673,5346 +2674,5348 +2675,5350 +2676,5352 +2677,5354 +2678,5356 +2679,5358 +2680,5360 +2681,5362 +2682,5364 +2683,5366 +2684,5368 +2685,5370 +2686,5372 +2687,5374 +2688,5376 +2689,5378 +2690,5380 +2691,5382 +2692,5384 +2693,5386 +2694,5388 +2695,5390 +2696,5392 +2697,5394 +2698,5396 +2699,5398 +2700,5400 +2701,5402 +2702,5404 +2703,5406 +2704,5408 +2705,5410 +2706,5412 +2707,5414 +2708,5416 +2709,5418 +2710,5420 +2711,5422 +2712,5424 +2713,5426 +2714,5428 +2715,5430 +2716,5432 +2717,5434 +2718,5436 +2719,5438 +2720,5440 +2721,5442 +2722,5444 +2723,5446 +2724,5448 +2725,5450 +2726,5452 +2727,5454 +2728,5456 +2729,5458 +2730,5460 +2731,5462 +2732,5464 +2733,5466 +2734,5468 +2735,5470 +2736,5472 +2737,5474 +2738,5476 +2739,5478 +2740,5480 +2741,5482 +2742,5484 +2743,5486 +2744,5488 +2745,5490 +2746,5492 +2747,5494 +2748,5496 +2749,5498 +2750,5500 +2751,5502 +2752,5504 +2753,5506 +2754,5508 +2755,5510 +2756,5512 +2757,5514 +2758,5516 +2759,5518 +2760,5520 +2761,5522 +2762,5524 +2763,5526 +2764,5528 +2765,5530 +2766,5532 +2767,5534 +2768,5536 +2769,5538 +2770,5540 +2771,5542 +2772,5544 +2773,5546 +2774,5548 +2775,5550 +2776,5552 +2777,5554 +2778,5556 +2779,5558 +2780,5560 +2781,5562 +2782,5564 +2783,5566 +2784,5568 +2785,5570 +2786,5572 +2787,5574 +2788,5576 +2789,5578 +2790,5580 +2791,5582 +2792,5584 +2793,5586 +2794,5588 +2795,5590 +2796,5592 +2797,5594 +2798,5596 +2799,5598 +2800,5600 +2801,5602 +2802,5604 +2803,5606 +2804,5608 +2805,5610 +2806,5612 +2807,5614 +2808,5616 +2809,5618 +2810,5620 +2811,5622 +2812,5624 +2813,5626 +2814,5628 +2815,5630 +2816,5632 +2817,5634 +2818,5636 +2819,5638 +2820,5640 +2821,5642 +2822,5644 +2823,5646 +2824,5648 +2825,5650 +2826,5652 +2827,5654 +2828,5656 +2829,5658 +2830,5660 +2831,5662 +2832,5664 +2833,5666 +2834,5668 +2835,5670 +2836,5672 +2837,5674 +2838,5676 +2839,5678 +2840,5680 +2841,5682 +2842,5684 +2843,5686 +2844,5688 +2845,5690 +2846,5692 +2847,5694 +2848,5696 +2849,5698 +2850,5700 +2851,5702 +2852,5704 +2853,5706 +2854,5708 +2855,5710 +2856,5712 +2857,5714 +2858,5716 +2859,5718 +2860,5720 +2861,5722 +2862,5724 +2863,5726 +2864,5728 +2865,5730 +2866,5732 +2867,5734 +2868,5736 +2869,5738 +2870,5740 +2871,5742 +2872,5744 +2873,5746 +2874,5748 +2875,5750 +2876,5752 +2877,5754 +2878,5756 +2879,5758 +2880,5760 +2881,5762 +2882,5764 +2883,5766 +2884,5768 +2885,5770 +2886,5772 +2887,5774 +2888,5776 +2889,5778 +2890,5780 +2891,5782 +2892,5784 +2893,5786 +2894,5788 +2895,5790 +2896,5792 +2897,5794 +2898,5796 +2899,5798 +2900,5800 +2901,5802 +2902,5804 +2903,5806 +2904,5808 +2905,5810 +2906,5812 +2907,5814 +2908,5816 +2909,5818 +2910,5820 +2911,5822 +2912,5824 +2913,5826 +2914,5828 +2915,5830 +2916,5832 +2917,5834 +2918,5836 +2919,5838 +2920,5840 +2921,5842 +2922,5844 +2923,5846 +2924,5848 +2925,5850 +2926,5852 +2927,5854 +2928,5856 +2929,5858 +2930,5860 +2931,5862 +2932,5864 +2933,5866 +2934,5868 +2935,5870 +2936,5872 +2937,5874 +2938,5876 +2939,5878 +2940,5880 +2941,5882 +2942,5884 +2943,5886 +2944,5888 +2945,5890 +2946,5892 +2947,5894 +2948,5896 +2949,5898 +2950,5900 +2951,5902 +2952,5904 +2953,5906 +2954,5908 +2955,5910 +2956,5912 +2957,5914 +2958,5916 +2959,5918 +2960,5920 +2961,5922 +2962,5924 +2963,5926 +2964,5928 +2965,5930 +2966,5932 +2967,5934 +2968,5936 +2969,5938 +2970,5940 +2971,5942 +2972,5944 +2973,5946 +2974,5948 +2975,5950 +2976,5952 +2977,5954 +2978,5956 +2979,5958 +2980,5960 +2981,5962 +2982,5964 +2983,5966 +2984,5968 +2985,5970 +2986,5972 +2987,5974 +2988,5976 +2989,5978 +2990,5980 +2991,5982 +2992,5984 +2993,5986 +2994,5988 +2995,5990 +2996,5992 +2997,5994 +2998,5996 +2999,5998 +3000,6000 +3001,6002 +3002,6004 +3003,6006 +3004,6008 +3005,6010 +3006,6012 +3007,6014 +3008,6016 +3009,6018 +3010,6020 +3011,6022 +3012,6024 +3013,6026 +3014,6028 +3015,6030 +3016,6032 +3017,6034 +3018,6036 +3019,6038 +3020,6040 +3021,6042 +3022,6044 +3023,6046 +3024,6048 +3025,6050 +3026,6052 +3027,6054 +3028,6056 +3029,6058 +3030,6060 +3031,6062 +3032,6064 +3033,6066 +3034,6068 +3035,6070 +3036,6072 +3037,6074 +3038,6076 +3039,6078 +3040,6080 +3041,6082 +3042,6084 +3043,6086 +3044,6088 +3045,6090 +3046,6092 +3047,6094 +3048,6096 +3049,6098 +3050,6100 +3051,6102 +3052,6104 +3053,6106 +3054,6108 +3055,6110 +3056,6112 +3057,6114 +3058,6116 +3059,6118 +3060,6120 +3061,6122 +3062,6124 +3063,6126 +3064,6128 +3065,6130 +3066,6132 +3067,6134 +3068,6136 +3069,6138 +3070,6140 +3071,6142 +3072,6144 +3073,6146 +3074,6148 +3075,6150 +3076,6152 +3077,6154 +3078,6156 +3079,6158 +3080,6160 +3081,6162 +3082,6164 +3083,6166 +3084,6168 +3085,6170 +3086,6172 +3087,6174 +3088,6176 +3089,6178 +3090,6180 +3091,6182 +3092,6184 +3093,6186 +3094,6188 +3095,6190 +3096,6192 +3097,6194 +3098,6196 +3099,6198 +3100,6200 +3101,6202 +3102,6204 +3103,6206 +3104,6208 +3105,6210 +3106,6212 +3107,6214 +3108,6216 +3109,6218 +3110,6220 +3111,6222 +3112,6224 +3113,6226 +3114,6228 +3115,6230 +3116,6232 +3117,6234 +3118,6236 +3119,6238 +3120,6240 +3121,6242 +3122,6244 +3123,6246 +3124,6248 +3125,6250 +3126,6252 +3127,6254 +3128,6256 +3129,6258 +3130,6260 +3131,6262 +3132,6264 +3133,6266 +3134,6268 +3135,6270 +3136,6272 +3137,6274 +3138,6276 +3139,6278 +3140,6280 +3141,6282 +3142,6284 +3143,6286 +3144,6288 +3145,6290 +3146,6292 +3147,6294 +3148,6296 +3149,6298 +3150,6300 +3151,6302 +3152,6304 +3153,6306 +3154,6308 +3155,6310 +3156,6312 +3157,6314 +3158,6316 +3159,6318 +3160,6320 +3161,6322 +3162,6324 +3163,6326 +3164,6328 +3165,6330 +3166,6332 +3167,6334 +3168,6336 +3169,6338 +3170,6340 +3171,6342 +3172,6344 +3173,6346 +3174,6348 +3175,6350 +3176,6352 +3177,6354 +3178,6356 +3179,6358 +3180,6360 +3181,6362 +3182,6364 +3183,6366 +3184,6368 +3185,6370 +3186,6372 +3187,6374 +3188,6376 +3189,6378 +3190,6380 +3191,6382 +3192,6384 +3193,6386 +3194,6388 +3195,6390 +3196,6392 +3197,6394 +3198,6396 +3199,6398 +3200,6400 +3201,6402 +3202,6404 +3203,6406 +3204,6408 +3205,6410 +3206,6412 +3207,6414 +3208,6416 +3209,6418 +3210,6420 +3211,6422 +3212,6424 +3213,6426 +3214,6428 +3215,6430 +3216,6432 +3217,6434 +3218,6436 +3219,6438 +3220,6440 +3221,6442 +3222,6444 +3223,6446 +3224,6448 +3225,6450 +3226,6452 +3227,6454 +3228,6456 +3229,6458 +3230,6460 +3231,6462 +3232,6464 +3233,6466 +3234,6468 +3235,6470 +3236,6472 +3237,6474 +3238,6476 +3239,6478 +3240,6480 +3241,6482 +3242,6484 +3243,6486 +3244,6488 +3245,6490 +3246,6492 +3247,6494 +3248,6496 +3249,6498 +3250,6500 +3251,6502 +3252,6504 +3253,6506 +3254,6508 +3255,6510 +3256,6512 +3257,6514 +3258,6516 +3259,6518 +3260,6520 +3261,6522 +3262,6524 +3263,6526 +3264,6528 +3265,6530 +3266,6532 +3267,6534 +3268,6536 +3269,6538 +3270,6540 +3271,6542 +3272,6544 +3273,6546 +3274,6548 +3275,6550 +3276,6552 +3277,6554 +3278,6556 +3279,6558 +3280,6560 +3281,6562 +3282,6564 +3283,6566 +3284,6568 +3285,6570 +3286,6572 +3287,6574 +3288,6576 +3289,6578 +3290,6580 +3291,6582 +3292,6584 +3293,6586 +3294,6588 +3295,6590 +3296,6592 +3297,6594 +3298,6596 +3299,6598 +3300,6600 +3301,6602 +3302,6604 +3303,6606 +3304,6608 +3305,6610 +3306,6612 +3307,6614 +3308,6616 +3309,6618 +3310,6620 +3311,6622 +3312,6624 +3313,6626 +3314,6628 +3315,6630 +3316,6632 +3317,6634 +3318,6636 +3319,6638 +3320,6640 +3321,6642 +3322,6644 +3323,6646 +3324,6648 +3325,6650 +3326,6652 +3327,6654 +3328,6656 +3329,6658 +3330,6660 +3331,6662 +3332,6664 +3333,6666 +3334,6668 +3335,6670 +3336,6672 +3337,6674 +3338,6676 +3339,6678 +3340,6680 +3341,6682 +3342,6684 +3343,6686 +3344,6688 +3345,6690 +3346,6692 +3347,6694 +3348,6696 +3349,6698 +3350,6700 +3351,6702 +3352,6704 +3353,6706 +3354,6708 +3355,6710 +3356,6712 +3357,6714 +3358,6716 +3359,6718 +3360,6720 +3361,6722 +3362,6724 +3363,6726 +3364,6728 +3365,6730 +3366,6732 +3367,6734 +3368,6736 +3369,6738 +3370,6740 +3371,6742 +3372,6744 +3373,6746 +3374,6748 +3375,6750 +3376,6752 +3377,6754 +3378,6756 +3379,6758 +3380,6760 +3381,6762 +3382,6764 +3383,6766 +3384,6768 +3385,6770 +3386,6772 +3387,6774 +3388,6776 +3389,6778 +3390,6780 +3391,6782 +3392,6784 +3393,6786 +3394,6788 +3395,6790 +3396,6792 +3397,6794 +3398,6796 +3399,6798 +3400,6800 +3401,6802 +3402,6804 +3403,6806 +3404,6808 +3405,6810 +3406,6812 +3407,6814 +3408,6816 +3409,6818 +3410,6820 +3411,6822 +3412,6824 +3413,6826 +3414,6828 +3415,6830 +3416,6832 +3417,6834 +3418,6836 +3419,6838 +3420,6840 +3421,6842 +3422,6844 +3423,6846 +3424,6848 +3425,6850 +3426,6852 +3427,6854 +3428,6856 +3429,6858 +3430,6860 +3431,6862 +3432,6864 +3433,6866 +3434,6868 +3435,6870 +3436,6872 +3437,6874 +3438,6876 +3439,6878 +3440,6880 +3441,6882 +3442,6884 +3443,6886 +3444,6888 +3445,6890 +3446,6892 +3447,6894 +3448,6896 +3449,6898 +3450,6900 +3451,6902 +3452,6904 +3453,6906 +3454,6908 +3455,6910 +3456,6912 +3457,6914 +3458,6916 +3459,6918 +3460,6920 +3461,6922 +3462,6924 +3463,6926 +3464,6928 +3465,6930 +3466,6932 +3467,6934 +3468,6936 +3469,6938 +3470,6940 +3471,6942 +3472,6944 +3473,6946 +3474,6948 +3475,6950 +3476,6952 +3477,6954 +3478,6956 +3479,6958 +3480,6960 +3481,6962 +3482,6964 +3483,6966 +3484,6968 +3485,6970 +3486,6972 +3487,6974 +3488,6976 +3489,6978 +3490,6980 +3491,6982 +3492,6984 +3493,6986 +3494,6988 +3495,6990 +3496,6992 +3497,6994 +3498,6996 +3499,6998 +3500,7000 +3501,7002 +3502,7004 +3503,7006 +3504,7008 +3505,7010 +3506,7012 +3507,7014 +3508,7016 +3509,7018 +3510,7020 +3511,7022 +3512,7024 +3513,7026 +3514,7028 +3515,7030 +3516,7032 +3517,7034 +3518,7036 +3519,7038 +3520,7040 +3521,7042 +3522,7044 +3523,7046 +3524,7048 +3525,7050 +3526,7052 +3527,7054 +3528,7056 +3529,7058 +3530,7060 +3531,7062 +3532,7064 +3533,7066 +3534,7068 +3535,7070 +3536,7072 +3537,7074 +3538,7076 +3539,7078 +3540,7080 +3541,7082 +3542,7084 +3543,7086 +3544,7088 +3545,7090 +3546,7092 +3547,7094 +3548,7096 +3549,7098 +3550,7100 +3551,7102 +3552,7104 +3553,7106 +3554,7108 +3555,7110 +3556,7112 +3557,7114 +3558,7116 +3559,7118 +3560,7120 +3561,7122 +3562,7124 +3563,7126 +3564,7128 +3565,7130 +3566,7132 +3567,7134 +3568,7136 +3569,7138 +3570,7140 +3571,7142 +3572,7144 +3573,7146 +3574,7148 +3575,7150 +3576,7152 +3577,7154 +3578,7156 +3579,7158 +3580,7160 +3581,7162 +3582,7164 +3583,7166 +3584,7168 +3585,7170 +3586,7172 +3587,7174 +3588,7176 +3589,7178 +3590,7180 +3591,7182 +3592,7184 +3593,7186 +3594,7188 +3595,7190 +3596,7192 +3597,7194 +3598,7196 +3599,7198 +3600,7200 +3601,7202 +3602,7204 +3603,7206 +3604,7208 +3605,7210 +3606,7212 +3607,7214 +3608,7216 +3609,7218 +3610,7220 +3611,7222 +3612,7224 +3613,7226 +3614,7228 +3615,7230 +3616,7232 +3617,7234 +3618,7236 +3619,7238 +3620,7240 +3621,7242 +3622,7244 +3623,7246 +3624,7248 +3625,7250 +3626,7252 +3627,7254 +3628,7256 +3629,7258 +3630,7260 +3631,7262 +3632,7264 +3633,7266 +3634,7268 +3635,7270 +3636,7272 +3637,7274 +3638,7276 +3639,7278 +3640,7280 +3641,7282 +3642,7284 +3643,7286 +3644,7288 +3645,7290 +3646,7292 +3647,7294 +3648,7296 +3649,7298 +3650,7300 +3651,7302 +3652,7304 +3653,7306 +3654,7308 +3655,7310 +3656,7312 +3657,7314 +3658,7316 +3659,7318 +3660,7320 +3661,7322 +3662,7324 +3663,7326 +3664,7328 +3665,7330 +3666,7332 +3667,7334 +3668,7336 +3669,7338 +3670,7340 +3671,7342 +3672,7344 +3673,7346 +3674,7348 +3675,7350 +3676,7352 +3677,7354 +3678,7356 +3679,7358 +3680,7360 +3681,7362 +3682,7364 +3683,7366 +3684,7368 +3685,7370 +3686,7372 +3687,7374 +3688,7376 +3689,7378 +3690,7380 +3691,7382 +3692,7384 +3693,7386 +3694,7388 +3695,7390 +3696,7392 +3697,7394 +3698,7396 +3699,7398 +3700,7400 +3701,7402 +3702,7404 +3703,7406 +3704,7408 +3705,7410 +3706,7412 +3707,7414 +3708,7416 +3709,7418 +3710,7420 +3711,7422 +3712,7424 +3713,7426 +3714,7428 +3715,7430 +3716,7432 +3717,7434 +3718,7436 +3719,7438 +3720,7440 +3721,7442 +3722,7444 +3723,7446 +3724,7448 +3725,7450 +3726,7452 +3727,7454 +3728,7456 +3729,7458 +3730,7460 +3731,7462 +3732,7464 +3733,7466 +3734,7468 +3735,7470 +3736,7472 +3737,7474 +3738,7476 +3739,7478 +3740,7480 +3741,7482 +3742,7484 +3743,7486 +3744,7488 +3745,7490 +3746,7492 +3747,7494 +3748,7496 +3749,7498 +3750,7500 +3751,7502 +3752,7504 +3753,7506 +3754,7508 +3755,7510 +3756,7512 +3757,7514 +3758,7516 +3759,7518 +3760,7520 +3761,7522 +3762,7524 +3763,7526 +3764,7528 +3765,7530 +3766,7532 +3767,7534 +3768,7536 +3769,7538 +3770,7540 +3771,7542 +3772,7544 +3773,7546 +3774,7548 +3775,7550 +3776,7552 +3777,7554 +3778,7556 +3779,7558 +3780,7560 +3781,7562 +3782,7564 +3783,7566 +3784,7568 +3785,7570 +3786,7572 +3787,7574 +3788,7576 +3789,7578 +3790,7580 +3791,7582 +3792,7584 +3793,7586 +3794,7588 +3795,7590 +3796,7592 +3797,7594 +3798,7596 +3799,7598 +3800,7600 +3801,7602 +3802,7604 +3803,7606 +3804,7608 +3805,7610 +3806,7612 +3807,7614 +3808,7616 +3809,7618 +3810,7620 +3811,7622 +3812,7624 +3813,7626 +3814,7628 +3815,7630 +3816,7632 +3817,7634 +3818,7636 +3819,7638 +3820,7640 +3821,7642 +3822,7644 +3823,7646 +3824,7648 +3825,7650 +3826,7652 +3827,7654 +3828,7656 +3829,7658 +3830,7660 +3831,7662 +3832,7664 +3833,7666 +3834,7668 +3835,7670 +3836,7672 +3837,7674 +3838,7676 +3839,7678 +3840,7680 +3841,7682 +3842,7684 +3843,7686 +3844,7688 +3845,7690 +3846,7692 +3847,7694 +3848,7696 +3849,7698 +3850,7700 +3851,7702 +3852,7704 +3853,7706 +3854,7708 +3855,7710 +3856,7712 +3857,7714 +3858,7716 +3859,7718 +3860,7720 +3861,7722 +3862,7724 +3863,7726 +3864,7728 +3865,7730 +3866,7732 +3867,7734 +3868,7736 +3869,7738 +3870,7740 +3871,7742 +3872,7744 +3873,7746 +3874,7748 +3875,7750 +3876,7752 +3877,7754 +3878,7756 +3879,7758 +3880,7760 +3881,7762 +3882,7764 +3883,7766 +3884,7768 +3885,7770 +3886,7772 +3887,7774 +3888,7776 +3889,7778 +3890,7780 +3891,7782 +3892,7784 +3893,7786 +3894,7788 +3895,7790 +3896,7792 +3897,7794 +3898,7796 +3899,7798 +3900,7800 +3901,7802 +3902,7804 +3903,7806 +3904,7808 +3905,7810 +3906,7812 +3907,7814 +3908,7816 +3909,7818 +3910,7820 +3911,7822 +3912,7824 +3913,7826 +3914,7828 +3915,7830 +3916,7832 +3917,7834 +3918,7836 +3919,7838 +3920,7840 +3921,7842 +3922,7844 +3923,7846 +3924,7848 +3925,7850 +3926,7852 +3927,7854 +3928,7856 +3929,7858 +3930,7860 +3931,7862 +3932,7864 +3933,7866 +3934,7868 +3935,7870 +3936,7872 +3937,7874 +3938,7876 +3939,7878 +3940,7880 +3941,7882 +3942,7884 +3943,7886 +3944,7888 +3945,7890 +3946,7892 +3947,7894 +3948,7896 +3949,7898 +3950,7900 +3951,7902 +3952,7904 +3953,7906 +3954,7908 +3955,7910 +3956,7912 +3957,7914 +3958,7916 +3959,7918 +3960,7920 +3961,7922 +3962,7924 +3963,7926 +3964,7928 +3965,7930 +3966,7932 +3967,7934 +3968,7936 +3969,7938 +3970,7940 +3971,7942 +3972,7944 +3973,7946 +3974,7948 +3975,7950 +3976,7952 +3977,7954 +3978,7956 +3979,7958 +3980,7960 +3981,7962 +3982,7964 +3983,7966 +3984,7968 +3985,7970 +3986,7972 +3987,7974 +3988,7976 +3989,7978 +3990,7980 +3991,7982 +3992,7984 +3993,7986 +3994,7988 +3995,7990 +3996,7992 +3997,7994 +3998,7996 +3999,7998 +4000,8000 +4001,8002 +4002,8004 +4003,8006 +4004,8008 +4005,8010 +4006,8012 +4007,8014 +4008,8016 +4009,8018 +4010,8020 +4011,8022 +4012,8024 +4013,8026 +4014,8028 +4015,8030 +4016,8032 +4017,8034 +4018,8036 +4019,8038 +4020,8040 +4021,8042 +4022,8044 +4023,8046 +4024,8048 +4025,8050 +4026,8052 +4027,8054 +4028,8056 +4029,8058 +4030,8060 +4031,8062 +4032,8064 +4033,8066 +4034,8068 +4035,8070 +4036,8072 +4037,8074 +4038,8076 +4039,8078 +4040,8080 +4041,8082 +4042,8084 +4043,8086 +4044,8088 +4045,8090 +4046,8092 +4047,8094 +4048,8096 +4049,8098 +4050,8100 +4051,8102 +4052,8104 +4053,8106 +4054,8108 +4055,8110 +4056,8112 +4057,8114 +4058,8116 +4059,8118 +4060,8120 +4061,8122 +4062,8124 +4063,8126 +4064,8128 +4065,8130 +4066,8132 +4067,8134 +4068,8136 +4069,8138 +4070,8140 +4071,8142 +4072,8144 +4073,8146 +4074,8148 +4075,8150 +4076,8152 +4077,8154 +4078,8156 +4079,8158 +4080,8160 +4081,8162 +4082,8164 +4083,8166 +4084,8168 +4085,8170 +4086,8172 +4087,8174 +4088,8176 +4089,8178 +4090,8180 +4091,8182 +4092,8184 +4093,8186 +4094,8188 +4095,8190 +4096,8192 +4097,8194 +4098,8196 +4099,8198 +4100,8200 +4101,8202 +4102,8204 +4103,8206 +4104,8208 +4105,8210 +4106,8212 +4107,8214 +4108,8216 +4109,8218 +4110,8220 +4111,8222 +4112,8224 +4113,8226 +4114,8228 +4115,8230 +4116,8232 +4117,8234 +4118,8236 +4119,8238 +4120,8240 +4121,8242 +4122,8244 +4123,8246 +4124,8248 +4125,8250 +4126,8252 +4127,8254 +4128,8256 +4129,8258 +4130,8260 +4131,8262 +4132,8264 +4133,8266 +4134,8268 +4135,8270 +4136,8272 +4137,8274 +4138,8276 +4139,8278 +4140,8280 +4141,8282 +4142,8284 +4143,8286 +4144,8288 +4145,8290 +4146,8292 +4147,8294 +4148,8296 +4149,8298 +4150,8300 +4151,8302 +4152,8304 +4153,8306 +4154,8308 +4155,8310 +4156,8312 +4157,8314 +4158,8316 +4159,8318 +4160,8320 +4161,8322 +4162,8324 +4163,8326 +4164,8328 +4165,8330 +4166,8332 +4167,8334 +4168,8336 +4169,8338 +4170,8340 +4171,8342 +4172,8344 +4173,8346 +4174,8348 +4175,8350 +4176,8352 +4177,8354 +4178,8356 +4179,8358 +4180,8360 +4181,8362 +4182,8364 +4183,8366 +4184,8368 +4185,8370 +4186,8372 +4187,8374 +4188,8376 +4189,8378 +4190,8380 +4191,8382 +4192,8384 +4193,8386 +4194,8388 +4195,8390 +4196,8392 +4197,8394 +4198,8396 +4199,8398 +4200,8400 +4201,8402 +4202,8404 +4203,8406 +4204,8408 +4205,8410 +4206,8412 +4207,8414 +4208,8416 +4209,8418 +4210,8420 +4211,8422 +4212,8424 +4213,8426 +4214,8428 +4215,8430 +4216,8432 +4217,8434 +4218,8436 +4219,8438 +4220,8440 +4221,8442 +4222,8444 +4223,8446 +4224,8448 +4225,8450 +4226,8452 +4227,8454 +4228,8456 +4229,8458 +4230,8460 +4231,8462 +4232,8464 +4233,8466 +4234,8468 +4235,8470 +4236,8472 +4237,8474 +4238,8476 +4239,8478 +4240,8480 +4241,8482 +4242,8484 +4243,8486 +4244,8488 +4245,8490 +4246,8492 +4247,8494 +4248,8496 +4249,8498 +4250,8500 +4251,8502 +4252,8504 +4253,8506 +4254,8508 +4255,8510 +4256,8512 +4257,8514 +4258,8516 +4259,8518 +4260,8520 +4261,8522 +4262,8524 +4263,8526 +4264,8528 +4265,8530 +4266,8532 +4267,8534 +4268,8536 +4269,8538 +4270,8540 +4271,8542 +4272,8544 +4273,8546 +4274,8548 +4275,8550 +4276,8552 +4277,8554 +4278,8556 +4279,8558 +4280,8560 +4281,8562 +4282,8564 +4283,8566 +4284,8568 +4285,8570 +4286,8572 +4287,8574 +4288,8576 +4289,8578 +4290,8580 +4291,8582 +4292,8584 +4293,8586 +4294,8588 +4295,8590 +4296,8592 +4297,8594 +4298,8596 +4299,8598 +4300,8600 +4301,8602 +4302,8604 +4303,8606 +4304,8608 +4305,8610 +4306,8612 +4307,8614 +4308,8616 +4309,8618 +4310,8620 +4311,8622 +4312,8624 +4313,8626 +4314,8628 +4315,8630 +4316,8632 +4317,8634 +4318,8636 +4319,8638 +4320,8640 +4321,8642 +4322,8644 +4323,8646 +4324,8648 +4325,8650 +4326,8652 +4327,8654 +4328,8656 +4329,8658 +4330,8660 +4331,8662 +4332,8664 +4333,8666 +4334,8668 +4335,8670 +4336,8672 +4337,8674 +4338,8676 +4339,8678 +4340,8680 +4341,8682 +4342,8684 +4343,8686 +4344,8688 +4345,8690 +4346,8692 +4347,8694 +4348,8696 +4349,8698 +4350,8700 +4351,8702 +4352,8704 +4353,8706 +4354,8708 +4355,8710 +4356,8712 +4357,8714 +4358,8716 +4359,8718 +4360,8720 +4361,8722 +4362,8724 +4363,8726 +4364,8728 +4365,8730 +4366,8732 +4367,8734 +4368,8736 +4369,8738 +4370,8740 +4371,8742 +4372,8744 +4373,8746 +4374,8748 +4375,8750 +4376,8752 +4377,8754 +4378,8756 +4379,8758 +4380,8760 +4381,8762 +4382,8764 +4383,8766 +4384,8768 +4385,8770 +4386,8772 +4387,8774 +4388,8776 +4389,8778 +4390,8780 +4391,8782 +4392,8784 +4393,8786 +4394,8788 +4395,8790 +4396,8792 +4397,8794 +4398,8796 +4399,8798 +4400,8800 +4401,8802 +4402,8804 +4403,8806 +4404,8808 +4405,8810 +4406,8812 +4407,8814 +4408,8816 +4409,8818 +4410,8820 +4411,8822 +4412,8824 +4413,8826 +4414,8828 +4415,8830 +4416,8832 +4417,8834 +4418,8836 +4419,8838 +4420,8840 +4421,8842 +4422,8844 +4423,8846 +4424,8848 +4425,8850 +4426,8852 +4427,8854 +4428,8856 +4429,8858 +4430,8860 +4431,8862 +4432,8864 +4433,8866 +4434,8868 +4435,8870 +4436,8872 +4437,8874 +4438,8876 +4439,8878 +4440,8880 +4441,8882 +4442,8884 +4443,8886 +4444,8888 +4445,8890 +4446,8892 +4447,8894 +4448,8896 +4449,8898 +4450,8900 +4451,8902 +4452,8904 +4453,8906 +4454,8908 +4455,8910 +4456,8912 +4457,8914 +4458,8916 +4459,8918 +4460,8920 +4461,8922 +4462,8924 +4463,8926 +4464,8928 +4465,8930 +4466,8932 +4467,8934 +4468,8936 +4469,8938 +4470,8940 +4471,8942 +4472,8944 +4473,8946 +4474,8948 +4475,8950 +4476,8952 +4477,8954 +4478,8956 +4479,8958 +4480,8960 +4481,8962 +4482,8964 +4483,8966 +4484,8968 +4485,8970 +4486,8972 +4487,8974 +4488,8976 +4489,8978 +4490,8980 +4491,8982 +4492,8984 +4493,8986 +4494,8988 +4495,8990 +4496,8992 +4497,8994 +4498,8996 +4499,8998 +4500,9000 +4501,9002 +4502,9004 +4503,9006 +4504,9008 +4505,9010 +4506,9012 +4507,9014 +4508,9016 +4509,9018 +4510,9020 +4511,9022 +4512,9024 +4513,9026 +4514,9028 +4515,9030 +4516,9032 +4517,9034 +4518,9036 +4519,9038 +4520,9040 +4521,9042 +4522,9044 +4523,9046 +4524,9048 +4525,9050 +4526,9052 +4527,9054 +4528,9056 +4529,9058 +4530,9060 +4531,9062 +4532,9064 +4533,9066 +4534,9068 +4535,9070 +4536,9072 +4537,9074 +4538,9076 +4539,9078 +4540,9080 +4541,9082 +4542,9084 +4543,9086 +4544,9088 +4545,9090 +4546,9092 +4547,9094 +4548,9096 +4549,9098 +4550,9100 +4551,9102 +4552,9104 +4553,9106 +4554,9108 +4555,9110 +4556,9112 +4557,9114 +4558,9116 +4559,9118 +4560,9120 +4561,9122 +4562,9124 +4563,9126 +4564,9128 +4565,9130 +4566,9132 +4567,9134 +4568,9136 +4569,9138 +4570,9140 +4571,9142 +4572,9144 +4573,9146 +4574,9148 +4575,9150 +4576,9152 +4577,9154 +4578,9156 +4579,9158 +4580,9160 +4581,9162 +4582,9164 +4583,9166 +4584,9168 +4585,9170 +4586,9172 +4587,9174 +4588,9176 +4589,9178 +4590,9180 +4591,9182 +4592,9184 +4593,9186 +4594,9188 +4595,9190 +4596,9192 +4597,9194 +4598,9196 +4599,9198 +4600,9200 +4601,9202 +4602,9204 +4603,9206 +4604,9208 +4605,9210 +4606,9212 +4607,9214 +4608,9216 +4609,9218 +4610,9220 +4611,9222 +4612,9224 +4613,9226 +4614,9228 +4615,9230 +4616,9232 +4617,9234 +4618,9236 +4619,9238 +4620,9240 +4621,9242 +4622,9244 +4623,9246 +4624,9248 +4625,9250 +4626,9252 +4627,9254 +4628,9256 +4629,9258 +4630,9260 +4631,9262 +4632,9264 +4633,9266 +4634,9268 +4635,9270 +4636,9272 +4637,9274 +4638,9276 +4639,9278 +4640,9280 +4641,9282 +4642,9284 +4643,9286 +4644,9288 +4645,9290 +4646,9292 +4647,9294 +4648,9296 +4649,9298 +4650,9300 +4651,9302 +4652,9304 +4653,9306 +4654,9308 +4655,9310 +4656,9312 +4657,9314 +4658,9316 +4659,9318 +4660,9320 +4661,9322 +4662,9324 +4663,9326 +4664,9328 +4665,9330 +4666,9332 +4667,9334 +4668,9336 +4669,9338 +4670,9340 +4671,9342 +4672,9344 +4673,9346 +4674,9348 +4675,9350 +4676,9352 +4677,9354 +4678,9356 +4679,9358 +4680,9360 +4681,9362 +4682,9364 +4683,9366 +4684,9368 +4685,9370 +4686,9372 +4687,9374 +4688,9376 +4689,9378 +4690,9380 +4691,9382 +4692,9384 +4693,9386 +4694,9388 +4695,9390 +4696,9392 +4697,9394 +4698,9396 +4699,9398 +4700,9400 +4701,9402 +4702,9404 +4703,9406 +4704,9408 +4705,9410 +4706,9412 +4707,9414 +4708,9416 +4709,9418 +4710,9420 +4711,9422 +4712,9424 +4713,9426 +4714,9428 +4715,9430 +4716,9432 +4717,9434 +4718,9436 +4719,9438 +4720,9440 +4721,9442 +4722,9444 +4723,9446 +4724,9448 +4725,9450 +4726,9452 +4727,9454 +4728,9456 +4729,9458 +4730,9460 +4731,9462 +4732,9464 +4733,9466 +4734,9468 +4735,9470 +4736,9472 +4737,9474 +4738,9476 +4739,9478 +4740,9480 +4741,9482 +4742,9484 +4743,9486 +4744,9488 +4745,9490 +4746,9492 +4747,9494 +4748,9496 +4749,9498 +4750,9500 +4751,9502 +4752,9504 +4753,9506 +4754,9508 +4755,9510 +4756,9512 +4757,9514 +4758,9516 +4759,9518 +4760,9520 +4761,9522 +4762,9524 +4763,9526 +4764,9528 +4765,9530 +4766,9532 +4767,9534 +4768,9536 +4769,9538 +4770,9540 +4771,9542 +4772,9544 +4773,9546 +4774,9548 +4775,9550 +4776,9552 +4777,9554 +4778,9556 +4779,9558 +4780,9560 +4781,9562 +4782,9564 +4783,9566 +4784,9568 +4785,9570 +4786,9572 +4787,9574 +4788,9576 +4789,9578 +4790,9580 +4791,9582 +4792,9584 +4793,9586 +4794,9588 +4795,9590 +4796,9592 +4797,9594 +4798,9596 +4799,9598 +4800,9600 +4801,9602 +4802,9604 +4803,9606 +4804,9608 +4805,9610 +4806,9612 +4807,9614 +4808,9616 +4809,9618 +4810,9620 +4811,9622 +4812,9624 +4813,9626 +4814,9628 +4815,9630 +4816,9632 +4817,9634 +4818,9636 +4819,9638 +4820,9640 +4821,9642 +4822,9644 +4823,9646 +4824,9648 +4825,9650 +4826,9652 +4827,9654 +4828,9656 +4829,9658 +4830,9660 +4831,9662 +4832,9664 +4833,9666 +4834,9668 +4835,9670 +4836,9672 +4837,9674 +4838,9676 +4839,9678 +4840,9680 +4841,9682 +4842,9684 +4843,9686 +4844,9688 +4845,9690 +4846,9692 +4847,9694 +4848,9696 +4849,9698 +4850,9700 +4851,9702 +4852,9704 +4853,9706 +4854,9708 +4855,9710 +4856,9712 +4857,9714 +4858,9716 +4859,9718 +4860,9720 +4861,9722 +4862,9724 +4863,9726 +4864,9728 +4865,9730 +4866,9732 +4867,9734 +4868,9736 +4869,9738 +4870,9740 +4871,9742 +4872,9744 +4873,9746 +4874,9748 +4875,9750 +4876,9752 +4877,9754 +4878,9756 +4879,9758 +4880,9760 +4881,9762 +4882,9764 +4883,9766 +4884,9768 +4885,9770 +4886,9772 +4887,9774 +4888,9776 +4889,9778 +4890,9780 +4891,9782 +4892,9784 +4893,9786 +4894,9788 +4895,9790 +4896,9792 +4897,9794 +4898,9796 +4899,9798 +4900,9800 +4901,9802 +4902,9804 +4903,9806 +4904,9808 +4905,9810 +4906,9812 +4907,9814 +4908,9816 +4909,9818 +4910,9820 +4911,9822 +4912,9824 +4913,9826 +4914,9828 +4915,9830 +4916,9832 +4917,9834 +4918,9836 +4919,9838 +4920,9840 +4921,9842 +4922,9844 +4923,9846 +4924,9848 +4925,9850 +4926,9852 +4927,9854 +4928,9856 +4929,9858 +4930,9860 +4931,9862 +4932,9864 +4933,9866 +4934,9868 +4935,9870 +4936,9872 +4937,9874 +4938,9876 +4939,9878 +4940,9880 +4941,9882 +4942,9884 +4943,9886 +4944,9888 +4945,9890 +4946,9892 +4947,9894 +4948,9896 +4949,9898 +4950,9900 +4951,9902 +4952,9904 +4953,9906 +4954,9908 +4955,9910 +4956,9912 +4957,9914 +4958,9916 +4959,9918 +4960,9920 +4961,9922 +4962,9924 +4963,9926 +4964,9928 +4965,9930 +4966,9932 +4967,9934 +4968,9936 +4969,9938 +4970,9940 +4971,9942 +4972,9944 +4973,9946 +4974,9948 +4975,9950 +4976,9952 +4977,9954 +4978,9956 +4979,9958 +4980,9960 +4981,9962 +4982,9964 +4983,9966 +4984,9968 +4985,9970 +4986,9972 +4987,9974 +4988,9976 +4989,9978 +4990,9980 +4991,9982 +4992,9984 +4993,9986 +4994,9988 +4995,9990 +4996,9992 +4997,9994 +4998,9996 +4999,9998 +5000,10000 +5001,10002 +5002,10004 +5003,10006 +5004,10008 +5005,10010 +5006,10012 +5007,10014 +5008,10016 +5009,10018 +5010,10020 +5011,10022 +5012,10024 +5013,10026 +5014,10028 +5015,10030 +5016,10032 +5017,10034 +5018,10036 +5019,10038 +5020,10040 +5021,10042 +5022,10044 +5023,10046 +5024,10048 +5025,10050 +5026,10052 +5027,10054 +5028,10056 +5029,10058 +5030,10060 +5031,10062 +5032,10064 +5033,10066 +5034,10068 +5035,10070 +5036,10072 +5037,10074 +5038,10076 +5039,10078 +5040,10080 +5041,10082 +5042,10084 +5043,10086 +5044,10088 +5045,10090 +5046,10092 +5047,10094 +5048,10096 +5049,10098 +5050,10100 +5051,10102 +5052,10104 +5053,10106 +5054,10108 +5055,10110 +5056,10112 +5057,10114 +5058,10116 +5059,10118 +5060,10120 +5061,10122 +5062,10124 +5063,10126 +5064,10128 +5065,10130 +5066,10132 +5067,10134 +5068,10136 +5069,10138 +5070,10140 +5071,10142 +5072,10144 +5073,10146 +5074,10148 +5075,10150 +5076,10152 +5077,10154 +5078,10156 +5079,10158 +5080,10160 +5081,10162 +5082,10164 +5083,10166 +5084,10168 +5085,10170 +5086,10172 +5087,10174 +5088,10176 +5089,10178 +5090,10180 +5091,10182 +5092,10184 +5093,10186 +5094,10188 +5095,10190 +5096,10192 +5097,10194 +5098,10196 +5099,10198 +5100,10200 +5101,10202 +5102,10204 +5103,10206 +5104,10208 +5105,10210 +5106,10212 +5107,10214 +5108,10216 +5109,10218 +5110,10220 +5111,10222 +5112,10224 +5113,10226 +5114,10228 +5115,10230 +5116,10232 +5117,10234 +5118,10236 +5119,10238 +5120,10240 +5121,10242 +5122,10244 +5123,10246 +5124,10248 +5125,10250 +5126,10252 +5127,10254 +5128,10256 +5129,10258 +5130,10260 +5131,10262 +5132,10264 +5133,10266 +5134,10268 +5135,10270 +5136,10272 +5137,10274 +5138,10276 +5139,10278 +5140,10280 +5141,10282 +5142,10284 +5143,10286 +5144,10288 +5145,10290 +5146,10292 +5147,10294 +5148,10296 +5149,10298 +5150,10300 +5151,10302 +5152,10304 +5153,10306 +5154,10308 +5155,10310 +5156,10312 +5157,10314 +5158,10316 +5159,10318 +5160,10320 +5161,10322 +5162,10324 +5163,10326 +5164,10328 +5165,10330 +5166,10332 +5167,10334 +5168,10336 +5169,10338 +5170,10340 +5171,10342 +5172,10344 +5173,10346 +5174,10348 +5175,10350 +5176,10352 +5177,10354 +5178,10356 +5179,10358 +5180,10360 +5181,10362 +5182,10364 +5183,10366 +5184,10368 +5185,10370 +5186,10372 +5187,10374 +5188,10376 +5189,10378 +5190,10380 +5191,10382 +5192,10384 +5193,10386 +5194,10388 +5195,10390 +5196,10392 +5197,10394 +5198,10396 +5199,10398 +5200,10400 +5201,10402 +5202,10404 +5203,10406 +5204,10408 +5205,10410 +5206,10412 +5207,10414 +5208,10416 +5209,10418 +5210,10420 +5211,10422 +5212,10424 +5213,10426 +5214,10428 +5215,10430 +5216,10432 +5217,10434 +5218,10436 +5219,10438 +5220,10440 +5221,10442 +5222,10444 +5223,10446 +5224,10448 +5225,10450 +5226,10452 +5227,10454 +5228,10456 +5229,10458 +5230,10460 +5231,10462 +5232,10464 +5233,10466 +5234,10468 +5235,10470 +5236,10472 +5237,10474 +5238,10476 +5239,10478 +5240,10480 +5241,10482 +5242,10484 +5243,10486 +5244,10488 +5245,10490 +5246,10492 +5247,10494 +5248,10496 +5249,10498 +5250,10500 +5251,10502 +5252,10504 +5253,10506 +5254,10508 +5255,10510 +5256,10512 +5257,10514 +5258,10516 +5259,10518 +5260,10520 +5261,10522 +5262,10524 +5263,10526 +5264,10528 +5265,10530 +5266,10532 +5267,10534 +5268,10536 +5269,10538 +5270,10540 +5271,10542 +5272,10544 +5273,10546 +5274,10548 +5275,10550 +5276,10552 +5277,10554 +5278,10556 +5279,10558 +5280,10560 +5281,10562 +5282,10564 +5283,10566 +5284,10568 +5285,10570 +5286,10572 +5287,10574 +5288,10576 +5289,10578 +5290,10580 +5291,10582 +5292,10584 +5293,10586 +5294,10588 +5295,10590 +5296,10592 +5297,10594 +5298,10596 +5299,10598 +5300,10600 +5301,10602 +5302,10604 +5303,10606 +5304,10608 +5305,10610 +5306,10612 +5307,10614 +5308,10616 +5309,10618 +5310,10620 +5311,10622 +5312,10624 +5313,10626 +5314,10628 +5315,10630 +5316,10632 +5317,10634 +5318,10636 +5319,10638 +5320,10640 +5321,10642 +5322,10644 +5323,10646 +5324,10648 +5325,10650 +5326,10652 +5327,10654 +5328,10656 +5329,10658 +5330,10660 +5331,10662 +5332,10664 +5333,10666 +5334,10668 +5335,10670 +5336,10672 +5337,10674 +5338,10676 +5339,10678 +5340,10680 +5341,10682 +5342,10684 +5343,10686 +5344,10688 +5345,10690 +5346,10692 +5347,10694 +5348,10696 +5349,10698 +5350,10700 +5351,10702 +5352,10704 +5353,10706 +5354,10708 +5355,10710 +5356,10712 +5357,10714 +5358,10716 +5359,10718 +5360,10720 +5361,10722 +5362,10724 +5363,10726 +5364,10728 +5365,10730 +5366,10732 +5367,10734 +5368,10736 +5369,10738 +5370,10740 +5371,10742 +5372,10744 +5373,10746 +5374,10748 +5375,10750 +5376,10752 +5377,10754 +5378,10756 +5379,10758 +5380,10760 +5381,10762 +5382,10764 +5383,10766 +5384,10768 +5385,10770 +5386,10772 +5387,10774 +5388,10776 +5389,10778 +5390,10780 +5391,10782 +5392,10784 +5393,10786 +5394,10788 +5395,10790 +5396,10792 +5397,10794 +5398,10796 +5399,10798 +5400,10800 +5401,10802 +5402,10804 +5403,10806 +5404,10808 +5405,10810 +5406,10812 +5407,10814 +5408,10816 +5409,10818 +5410,10820 +5411,10822 +5412,10824 +5413,10826 +5414,10828 +5415,10830 +5416,10832 +5417,10834 +5418,10836 +5419,10838 +5420,10840 +5421,10842 +5422,10844 +5423,10846 +5424,10848 +5425,10850 +5426,10852 +5427,10854 +5428,10856 +5429,10858 +5430,10860 +5431,10862 +5432,10864 +5433,10866 +5434,10868 +5435,10870 +5436,10872 +5437,10874 +5438,10876 +5439,10878 +5440,10880 +5441,10882 +5442,10884 +5443,10886 +5444,10888 +5445,10890 +5446,10892 +5447,10894 +5448,10896 +5449,10898 +5450,10900 +5451,10902 +5452,10904 +5453,10906 +5454,10908 +5455,10910 +5456,10912 +5457,10914 +5458,10916 +5459,10918 +5460,10920 +5461,10922 +5462,10924 +5463,10926 +5464,10928 +5465,10930 +5466,10932 +5467,10934 +5468,10936 +5469,10938 +5470,10940 +5471,10942 +5472,10944 +5473,10946 +5474,10948 +5475,10950 +5476,10952 +5477,10954 +5478,10956 +5479,10958 +5480,10960 +5481,10962 +5482,10964 +5483,10966 +5484,10968 +5485,10970 +5486,10972 +5487,10974 +5488,10976 +5489,10978 +5490,10980 +5491,10982 +5492,10984 +5493,10986 +5494,10988 +5495,10990 +5496,10992 +5497,10994 +5498,10996 +5499,10998 +5500,11000 +5501,11002 +5502,11004 +5503,11006 +5504,11008 +5505,11010 +5506,11012 +5507,11014 +5508,11016 +5509,11018 +5510,11020 +5511,11022 +5512,11024 +5513,11026 +5514,11028 +5515,11030 +5516,11032 +5517,11034 +5518,11036 +5519,11038 +5520,11040 +5521,11042 +5522,11044 +5523,11046 +5524,11048 +5525,11050 +5526,11052 +5527,11054 +5528,11056 +5529,11058 +5530,11060 +5531,11062 +5532,11064 +5533,11066 +5534,11068 +5535,11070 +5536,11072 +5537,11074 +5538,11076 +5539,11078 +5540,11080 +5541,11082 +5542,11084 +5543,11086 +5544,11088 +5545,11090 +5546,11092 +5547,11094 +5548,11096 +5549,11098 +5550,11100 +5551,11102 +5552,11104 +5553,11106 +5554,11108 +5555,11110 +5556,11112 +5557,11114 +5558,11116 +5559,11118 +5560,11120 +5561,11122 +5562,11124 +5563,11126 +5564,11128 +5565,11130 +5566,11132 +5567,11134 +5568,11136 +5569,11138 +5570,11140 +5571,11142 +5572,11144 +5573,11146 +5574,11148 +5575,11150 +5576,11152 +5577,11154 +5578,11156 +5579,11158 +5580,11160 +5581,11162 +5582,11164 +5583,11166 +5584,11168 +5585,11170 +5586,11172 +5587,11174 +5588,11176 +5589,11178 +5590,11180 +5591,11182 +5592,11184 +5593,11186 +5594,11188 +5595,11190 +5596,11192 +5597,11194 +5598,11196 +5599,11198 +5600,11200 +5601,11202 +5602,11204 +5603,11206 +5604,11208 +5605,11210 +5606,11212 +5607,11214 +5608,11216 +5609,11218 +5610,11220 +5611,11222 +5612,11224 +5613,11226 +5614,11228 +5615,11230 +5616,11232 +5617,11234 +5618,11236 +5619,11238 +5620,11240 +5621,11242 +5622,11244 +5623,11246 +5624,11248 +5625,11250 +5626,11252 +5627,11254 +5628,11256 +5629,11258 +5630,11260 +5631,11262 +5632,11264 +5633,11266 +5634,11268 +5635,11270 +5636,11272 +5637,11274 +5638,11276 +5639,11278 +5640,11280 +5641,11282 +5642,11284 +5643,11286 +5644,11288 +5645,11290 +5646,11292 +5647,11294 +5648,11296 +5649,11298 +5650,11300 +5651,11302 +5652,11304 +5653,11306 +5654,11308 +5655,11310 +5656,11312 +5657,11314 +5658,11316 +5659,11318 +5660,11320 +5661,11322 +5662,11324 +5663,11326 +5664,11328 +5665,11330 +5666,11332 +5667,11334 +5668,11336 +5669,11338 +5670,11340 +5671,11342 +5672,11344 +5673,11346 +5674,11348 +5675,11350 +5676,11352 +5677,11354 +5678,11356 +5679,11358 +5680,11360 +5681,11362 +5682,11364 +5683,11366 +5684,11368 +5685,11370 +5686,11372 +5687,11374 +5688,11376 +5689,11378 +5690,11380 +5691,11382 +5692,11384 +5693,11386 +5694,11388 +5695,11390 +5696,11392 +5697,11394 +5698,11396 +5699,11398 +5700,11400 +5701,11402 +5702,11404 +5703,11406 +5704,11408 +5705,11410 +5706,11412 +5707,11414 +5708,11416 +5709,11418 +5710,11420 +5711,11422 +5712,11424 +5713,11426 +5714,11428 +5715,11430 +5716,11432 +5717,11434 +5718,11436 +5719,11438 +5720,11440 +5721,11442 +5722,11444 +5723,11446 +5724,11448 +5725,11450 +5726,11452 +5727,11454 +5728,11456 +5729,11458 +5730,11460 +5731,11462 +5732,11464 +5733,11466 +5734,11468 +5735,11470 +5736,11472 +5737,11474 +5738,11476 +5739,11478 +5740,11480 +5741,11482 +5742,11484 +5743,11486 +5744,11488 +5745,11490 +5746,11492 +5747,11494 +5748,11496 +5749,11498 +5750,11500 +5751,11502 +5752,11504 +5753,11506 +5754,11508 +5755,11510 +5756,11512 +5757,11514 +5758,11516 +5759,11518 +5760,11520 +5761,11522 +5762,11524 +5763,11526 +5764,11528 +5765,11530 +5766,11532 +5767,11534 +5768,11536 +5769,11538 +5770,11540 +5771,11542 +5772,11544 +5773,11546 +5774,11548 +5775,11550 +5776,11552 +5777,11554 +5778,11556 +5779,11558 +5780,11560 +5781,11562 +5782,11564 +5783,11566 +5784,11568 +5785,11570 +5786,11572 +5787,11574 +5788,11576 +5789,11578 +5790,11580 +5791,11582 +5792,11584 +5793,11586 +5794,11588 +5795,11590 +5796,11592 +5797,11594 +5798,11596 +5799,11598 +5800,11600 +5801,11602 +5802,11604 +5803,11606 +5804,11608 +5805,11610 +5806,11612 +5807,11614 +5808,11616 +5809,11618 +5810,11620 +5811,11622 +5812,11624 +5813,11626 +5814,11628 +5815,11630 +5816,11632 +5817,11634 +5818,11636 +5819,11638 +5820,11640 +5821,11642 +5822,11644 +5823,11646 +5824,11648 +5825,11650 +5826,11652 +5827,11654 +5828,11656 +5829,11658 +5830,11660 +5831,11662 +5832,11664 +5833,11666 +5834,11668 +5835,11670 +5836,11672 +5837,11674 +5838,11676 +5839,11678 +5840,11680 +5841,11682 +5842,11684 +5843,11686 +5844,11688 +5845,11690 +5846,11692 +5847,11694 +5848,11696 +5849,11698 +5850,11700 +5851,11702 +5852,11704 +5853,11706 +5854,11708 +5855,11710 +5856,11712 +5857,11714 +5858,11716 +5859,11718 +5860,11720 +5861,11722 +5862,11724 +5863,11726 +5864,11728 +5865,11730 +5866,11732 +5867,11734 +5868,11736 +5869,11738 +5870,11740 +5871,11742 +5872,11744 +5873,11746 +5874,11748 +5875,11750 +5876,11752 +5877,11754 +5878,11756 +5879,11758 +5880,11760 +5881,11762 +5882,11764 +5883,11766 +5884,11768 +5885,11770 +5886,11772 +5887,11774 +5888,11776 +5889,11778 +5890,11780 +5891,11782 +5892,11784 +5893,11786 +5894,11788 +5895,11790 +5896,11792 +5897,11794 +5898,11796 +5899,11798 +5900,11800 +5901,11802 +5902,11804 +5903,11806 +5904,11808 +5905,11810 +5906,11812 +5907,11814 +5908,11816 +5909,11818 +5910,11820 +5911,11822 +5912,11824 +5913,11826 +5914,11828 +5915,11830 +5916,11832 +5917,11834 +5918,11836 +5919,11838 +5920,11840 +5921,11842 +5922,11844 +5923,11846 +5924,11848 +5925,11850 +5926,11852 +5927,11854 +5928,11856 +5929,11858 +5930,11860 +5931,11862 +5932,11864 +5933,11866 +5934,11868 +5935,11870 +5936,11872 +5937,11874 +5938,11876 +5939,11878 +5940,11880 +5941,11882 +5942,11884 +5943,11886 +5944,11888 +5945,11890 +5946,11892 +5947,11894 +5948,11896 +5949,11898 +5950,11900 +5951,11902 +5952,11904 +5953,11906 +5954,11908 +5955,11910 +5956,11912 +5957,11914 +5958,11916 +5959,11918 +5960,11920 +5961,11922 +5962,11924 +5963,11926 +5964,11928 +5965,11930 +5966,11932 +5967,11934 +5968,11936 +5969,11938 +5970,11940 +5971,11942 +5972,11944 +5973,11946 +5974,11948 +5975,11950 +5976,11952 +5977,11954 +5978,11956 +5979,11958 +5980,11960 +5981,11962 +5982,11964 +5983,11966 +5984,11968 +5985,11970 +5986,11972 +5987,11974 +5988,11976 +5989,11978 +5990,11980 +5991,11982 +5992,11984 +5993,11986 +5994,11988 +5995,11990 +5996,11992 +5997,11994 +5998,11996 +5999,11998 +6000,12000 +6001,12002 +6002,12004 +6003,12006 +6004,12008 +6005,12010 +6006,12012 +6007,12014 +6008,12016 +6009,12018 +6010,12020 +6011,12022 +6012,12024 +6013,12026 +6014,12028 +6015,12030 +6016,12032 +6017,12034 +6018,12036 +6019,12038 +6020,12040 +6021,12042 +6022,12044 +6023,12046 +6024,12048 +6025,12050 +6026,12052 +6027,12054 +6028,12056 +6029,12058 +6030,12060 +6031,12062 +6032,12064 +6033,12066 +6034,12068 +6035,12070 +6036,12072 +6037,12074 +6038,12076 +6039,12078 +6040,12080 +6041,12082 +6042,12084 +6043,12086 +6044,12088 +6045,12090 +6046,12092 +6047,12094 +6048,12096 +6049,12098 +6050,12100 +6051,12102 +6052,12104 +6053,12106 +6054,12108 +6055,12110 +6056,12112 +6057,12114 +6058,12116 +6059,12118 +6060,12120 +6061,12122 +6062,12124 +6063,12126 +6064,12128 +6065,12130 +6066,12132 +6067,12134 +6068,12136 +6069,12138 +6070,12140 +6071,12142 +6072,12144 +6073,12146 +6074,12148 +6075,12150 +6076,12152 +6077,12154 +6078,12156 +6079,12158 +6080,12160 +6081,12162 +6082,12164 +6083,12166 +6084,12168 +6085,12170 +6086,12172 +6087,12174 +6088,12176 +6089,12178 +6090,12180 +6091,12182 +6092,12184 +6093,12186 +6094,12188 +6095,12190 +6096,12192 +6097,12194 +6098,12196 +6099,12198 +6100,12200 +6101,12202 +6102,12204 +6103,12206 +6104,12208 +6105,12210 +6106,12212 +6107,12214 +6108,12216 +6109,12218 +6110,12220 +6111,12222 +6112,12224 +6113,12226 +6114,12228 +6115,12230 +6116,12232 +6117,12234 +6118,12236 +6119,12238 +6120,12240 +6121,12242 +6122,12244 +6123,12246 +6124,12248 +6125,12250 +6126,12252 +6127,12254 +6128,12256 +6129,12258 +6130,12260 +6131,12262 +6132,12264 +6133,12266 +6134,12268 +6135,12270 +6136,12272 +6137,12274 +6138,12276 +6139,12278 +6140,12280 +6141,12282 +6142,12284 +6143,12286 +6144,12288 +6145,12290 +6146,12292 +6147,12294 +6148,12296 +6149,12298 +6150,12300 +6151,12302 +6152,12304 +6153,12306 +6154,12308 +6155,12310 +6156,12312 +6157,12314 +6158,12316 +6159,12318 +6160,12320 +6161,12322 +6162,12324 +6163,12326 +6164,12328 +6165,12330 +6166,12332 +6167,12334 +6168,12336 +6169,12338 +6170,12340 +6171,12342 +6172,12344 +6173,12346 +6174,12348 +6175,12350 +6176,12352 +6177,12354 +6178,12356 +6179,12358 +6180,12360 +6181,12362 +6182,12364 +6183,12366 +6184,12368 +6185,12370 +6186,12372 +6187,12374 +6188,12376 +6189,12378 +6190,12380 +6191,12382 +6192,12384 +6193,12386 +6194,12388 +6195,12390 +6196,12392 +6197,12394 +6198,12396 +6199,12398 +6200,12400 +6201,12402 +6202,12404 +6203,12406 +6204,12408 +6205,12410 +6206,12412 +6207,12414 +6208,12416 +6209,12418 +6210,12420 +6211,12422 +6212,12424 +6213,12426 +6214,12428 +6215,12430 +6216,12432 +6217,12434 +6218,12436 +6219,12438 +6220,12440 +6221,12442 +6222,12444 +6223,12446 +6224,12448 +6225,12450 +6226,12452 +6227,12454 +6228,12456 +6229,12458 +6230,12460 +6231,12462 +6232,12464 +6233,12466 +6234,12468 +6235,12470 +6236,12472 +6237,12474 +6238,12476 +6239,12478 +6240,12480 +6241,12482 +6242,12484 +6243,12486 +6244,12488 +6245,12490 +6246,12492 +6247,12494 +6248,12496 +6249,12498 +6250,12500 +6251,12502 +6252,12504 +6253,12506 +6254,12508 +6255,12510 +6256,12512 +6257,12514 +6258,12516 +6259,12518 +6260,12520 +6261,12522 +6262,12524 +6263,12526 +6264,12528 +6265,12530 +6266,12532 +6267,12534 +6268,12536 +6269,12538 +6270,12540 +6271,12542 +6272,12544 +6273,12546 +6274,12548 +6275,12550 +6276,12552 +6277,12554 +6278,12556 +6279,12558 +6280,12560 +6281,12562 +6282,12564 +6283,12566 +6284,12568 +6285,12570 +6286,12572 +6287,12574 +6288,12576 +6289,12578 +6290,12580 +6291,12582 +6292,12584 +6293,12586 +6294,12588 +6295,12590 +6296,12592 +6297,12594 +6298,12596 +6299,12598 +6300,12600 +6301,12602 +6302,12604 +6303,12606 +6304,12608 +6305,12610 +6306,12612 +6307,12614 +6308,12616 +6309,12618 +6310,12620 +6311,12622 +6312,12624 +6313,12626 +6314,12628 +6315,12630 +6316,12632 +6317,12634 +6318,12636 +6319,12638 +6320,12640 +6321,12642 +6322,12644 +6323,12646 +6324,12648 +6325,12650 +6326,12652 +6327,12654 +6328,12656 +6329,12658 +6330,12660 +6331,12662 +6332,12664 +6333,12666 +6334,12668 +6335,12670 +6336,12672 +6337,12674 +6338,12676 +6339,12678 +6340,12680 +6341,12682 +6342,12684 +6343,12686 +6344,12688 +6345,12690 +6346,12692 +6347,12694 +6348,12696 +6349,12698 +6350,12700 +6351,12702 +6352,12704 +6353,12706 +6354,12708 +6355,12710 +6356,12712 +6357,12714 +6358,12716 +6359,12718 +6360,12720 +6361,12722 +6362,12724 +6363,12726 +6364,12728 +6365,12730 +6366,12732 +6367,12734 +6368,12736 +6369,12738 +6370,12740 +6371,12742 +6372,12744 +6373,12746 +6374,12748 +6375,12750 +6376,12752 +6377,12754 +6378,12756 +6379,12758 +6380,12760 +6381,12762 +6382,12764 +6383,12766 +6384,12768 +6385,12770 +6386,12772 +6387,12774 +6388,12776 +6389,12778 +6390,12780 +6391,12782 +6392,12784 +6393,12786 +6394,12788 +6395,12790 +6396,12792 +6397,12794 +6398,12796 +6399,12798 +6400,12800 +6401,12802 +6402,12804 +6403,12806 +6404,12808 +6405,12810 +6406,12812 +6407,12814 +6408,12816 +6409,12818 +6410,12820 +6411,12822 +6412,12824 +6413,12826 +6414,12828 +6415,12830 +6416,12832 +6417,12834 +6418,12836 +6419,12838 +6420,12840 +6421,12842 +6422,12844 +6423,12846 +6424,12848 +6425,12850 +6426,12852 +6427,12854 +6428,12856 +6429,12858 +6430,12860 +6431,12862 +6432,12864 +6433,12866 +6434,12868 +6435,12870 +6436,12872 +6437,12874 +6438,12876 +6439,12878 +6440,12880 +6441,12882 +6442,12884 +6443,12886 +6444,12888 +6445,12890 +6446,12892 +6447,12894 +6448,12896 +6449,12898 +6450,12900 +6451,12902 +6452,12904 +6453,12906 +6454,12908 +6455,12910 +6456,12912 +6457,12914 +6458,12916 +6459,12918 +6460,12920 +6461,12922 +6462,12924 +6463,12926 +6464,12928 +6465,12930 +6466,12932 +6467,12934 +6468,12936 +6469,12938 +6470,12940 +6471,12942 +6472,12944 +6473,12946 +6474,12948 +6475,12950 +6476,12952 +6477,12954 +6478,12956 +6479,12958 +6480,12960 +6481,12962 +6482,12964 +6483,12966 +6484,12968 +6485,12970 +6486,12972 +6487,12974 +6488,12976 +6489,12978 +6490,12980 +6491,12982 +6492,12984 +6493,12986 +6494,12988 +6495,12990 +6496,12992 +6497,12994 +6498,12996 +6499,12998 +6500,13000 +6501,13002 +6502,13004 +6503,13006 +6504,13008 +6505,13010 +6506,13012 +6507,13014 +6508,13016 +6509,13018 +6510,13020 +6511,13022 +6512,13024 +6513,13026 +6514,13028 +6515,13030 +6516,13032 +6517,13034 +6518,13036 +6519,13038 +6520,13040 +6521,13042 +6522,13044 +6523,13046 +6524,13048 +6525,13050 +6526,13052 +6527,13054 +6528,13056 +6529,13058 +6530,13060 +6531,13062 +6532,13064 +6533,13066 +6534,13068 +6535,13070 +6536,13072 +6537,13074 +6538,13076 +6539,13078 +6540,13080 +6541,13082 +6542,13084 +6543,13086 +6544,13088 +6545,13090 +6546,13092 +6547,13094 +6548,13096 +6549,13098 +6550,13100 +6551,13102 +6552,13104 +6553,13106 +6554,13108 +6555,13110 +6556,13112 +6557,13114 +6558,13116 +6559,13118 +6560,13120 +6561,13122 +6562,13124 +6563,13126 +6564,13128 +6565,13130 +6566,13132 +6567,13134 +6568,13136 +6569,13138 +6570,13140 +6571,13142 +6572,13144 +6573,13146 +6574,13148 +6575,13150 +6576,13152 +6577,13154 +6578,13156 +6579,13158 +6580,13160 +6581,13162 +6582,13164 +6583,13166 +6584,13168 +6585,13170 +6586,13172 +6587,13174 +6588,13176 +6589,13178 +6590,13180 +6591,13182 +6592,13184 +6593,13186 +6594,13188 +6595,13190 +6596,13192 +6597,13194 +6598,13196 +6599,13198 +6600,13200 +6601,13202 +6602,13204 +6603,13206 +6604,13208 +6605,13210 +6606,13212 +6607,13214 +6608,13216 +6609,13218 +6610,13220 +6611,13222 +6612,13224 +6613,13226 +6614,13228 +6615,13230 +6616,13232 +6617,13234 +6618,13236 +6619,13238 +6620,13240 +6621,13242 +6622,13244 +6623,13246 +6624,13248 +6625,13250 +6626,13252 +6627,13254 +6628,13256 +6629,13258 +6630,13260 +6631,13262 +6632,13264 +6633,13266 +6634,13268 +6635,13270 +6636,13272 +6637,13274 +6638,13276 +6639,13278 +6640,13280 +6641,13282 +6642,13284 +6643,13286 +6644,13288 +6645,13290 +6646,13292 +6647,13294 +6648,13296 +6649,13298 +6650,13300 +6651,13302 +6652,13304 +6653,13306 +6654,13308 +6655,13310 +6656,13312 +6657,13314 +6658,13316 +6659,13318 +6660,13320 +6661,13322 +6662,13324 +6663,13326 +6664,13328 +6665,13330 +6666,13332 +6667,13334 +6668,13336 +6669,13338 +6670,13340 +6671,13342 +6672,13344 +6673,13346 +6674,13348 +6675,13350 +6676,13352 +6677,13354 +6678,13356 +6679,13358 +6680,13360 +6681,13362 +6682,13364 +6683,13366 +6684,13368 +6685,13370 +6686,13372 +6687,13374 +6688,13376 +6689,13378 +6690,13380 +6691,13382 +6692,13384 +6693,13386 +6694,13388 +6695,13390 +6696,13392 +6697,13394 +6698,13396 +6699,13398 +6700,13400 +6701,13402 +6702,13404 +6703,13406 +6704,13408 +6705,13410 +6706,13412 +6707,13414 +6708,13416 +6709,13418 +6710,13420 +6711,13422 +6712,13424 +6713,13426 +6714,13428 +6715,13430 +6716,13432 +6717,13434 +6718,13436 +6719,13438 +6720,13440 +6721,13442 +6722,13444 +6723,13446 +6724,13448 +6725,13450 +6726,13452 +6727,13454 +6728,13456 +6729,13458 +6730,13460 +6731,13462 +6732,13464 +6733,13466 +6734,13468 +6735,13470 +6736,13472 +6737,13474 +6738,13476 +6739,13478 +6740,13480 +6741,13482 +6742,13484 +6743,13486 +6744,13488 +6745,13490 +6746,13492 +6747,13494 +6748,13496 +6749,13498 +6750,13500 +6751,13502 +6752,13504 +6753,13506 +6754,13508 +6755,13510 +6756,13512 +6757,13514 +6758,13516 +6759,13518 +6760,13520 +6761,13522 +6762,13524 +6763,13526 +6764,13528 +6765,13530 +6766,13532 +6767,13534 +6768,13536 +6769,13538 +6770,13540 +6771,13542 +6772,13544 +6773,13546 +6774,13548 +6775,13550 +6776,13552 +6777,13554 +6778,13556 +6779,13558 +6780,13560 +6781,13562 +6782,13564 +6783,13566 +6784,13568 +6785,13570 +6786,13572 +6787,13574 +6788,13576 +6789,13578 +6790,13580 +6791,13582 +6792,13584 +6793,13586 +6794,13588 +6795,13590 +6796,13592 +6797,13594 +6798,13596 +6799,13598 +6800,13600 +6801,13602 +6802,13604 +6803,13606 +6804,13608 +6805,13610 +6806,13612 +6807,13614 +6808,13616 +6809,13618 +6810,13620 +6811,13622 +6812,13624 +6813,13626 +6814,13628 +6815,13630 +6816,13632 +6817,13634 +6818,13636 +6819,13638 +6820,13640 +6821,13642 +6822,13644 +6823,13646 +6824,13648 +6825,13650 +6826,13652 +6827,13654 +6828,13656 +6829,13658 +6830,13660 +6831,13662 +6832,13664 +6833,13666 +6834,13668 +6835,13670 +6836,13672 +6837,13674 +6838,13676 +6839,13678 +6840,13680 +6841,13682 +6842,13684 +6843,13686 +6844,13688 +6845,13690 +6846,13692 +6847,13694 +6848,13696 +6849,13698 +6850,13700 +6851,13702 +6852,13704 +6853,13706 +6854,13708 +6855,13710 +6856,13712 +6857,13714 +6858,13716 +6859,13718 +6860,13720 +6861,13722 +6862,13724 +6863,13726 +6864,13728 +6865,13730 +6866,13732 +6867,13734 +6868,13736 +6869,13738 +6870,13740 +6871,13742 +6872,13744 +6873,13746 +6874,13748 +6875,13750 +6876,13752 +6877,13754 +6878,13756 +6879,13758 +6880,13760 +6881,13762 +6882,13764 +6883,13766 +6884,13768 +6885,13770 +6886,13772 +6887,13774 +6888,13776 +6889,13778 +6890,13780 +6891,13782 +6892,13784 +6893,13786 +6894,13788 +6895,13790 +6896,13792 +6897,13794 +6898,13796 +6899,13798 +6900,13800 +6901,13802 +6902,13804 +6903,13806 +6904,13808 +6905,13810 +6906,13812 +6907,13814 +6908,13816 +6909,13818 +6910,13820 +6911,13822 +6912,13824 +6913,13826 +6914,13828 +6915,13830 +6916,13832 +6917,13834 +6918,13836 +6919,13838 +6920,13840 +6921,13842 +6922,13844 +6923,13846 +6924,13848 +6925,13850 +6926,13852 +6927,13854 +6928,13856 +6929,13858 +6930,13860 +6931,13862 +6932,13864 +6933,13866 +6934,13868 +6935,13870 +6936,13872 +6937,13874 +6938,13876 +6939,13878 +6940,13880 +6941,13882 +6942,13884 +6943,13886 +6944,13888 +6945,13890 +6946,13892 +6947,13894 +6948,13896 +6949,13898 +6950,13900 +6951,13902 +6952,13904 +6953,13906 +6954,13908 +6955,13910 +6956,13912 +6957,13914 +6958,13916 +6959,13918 +6960,13920 +6961,13922 +6962,13924 +6963,13926 +6964,13928 +6965,13930 +6966,13932 +6967,13934 +6968,13936 +6969,13938 +6970,13940 +6971,13942 +6972,13944 +6973,13946 +6974,13948 +6975,13950 +6976,13952 +6977,13954 +6978,13956 +6979,13958 +6980,13960 +6981,13962 +6982,13964 +6983,13966 +6984,13968 +6985,13970 +6986,13972 +6987,13974 +6988,13976 +6989,13978 +6990,13980 +6991,13982 +6992,13984 +6993,13986 +6994,13988 +6995,13990 +6996,13992 +6997,13994 +6998,13996 +6999,13998 +7000,14000 +7001,14002 +7002,14004 +7003,14006 +7004,14008 +7005,14010 +7006,14012 +7007,14014 +7008,14016 +7009,14018 +7010,14020 +7011,14022 +7012,14024 +7013,14026 +7014,14028 +7015,14030 +7016,14032 +7017,14034 +7018,14036 +7019,14038 +7020,14040 +7021,14042 +7022,14044 +7023,14046 +7024,14048 +7025,14050 +7026,14052 +7027,14054 +7028,14056 +7029,14058 +7030,14060 +7031,14062 +7032,14064 +7033,14066 +7034,14068 +7035,14070 +7036,14072 +7037,14074 +7038,14076 +7039,14078 +7040,14080 +7041,14082 +7042,14084 +7043,14086 +7044,14088 +7045,14090 +7046,14092 +7047,14094 +7048,14096 +7049,14098 +7050,14100 +7051,14102 +7052,14104 +7053,14106 +7054,14108 +7055,14110 +7056,14112 +7057,14114 +7058,14116 +7059,14118 +7060,14120 +7061,14122 +7062,14124 +7063,14126 +7064,14128 +7065,14130 +7066,14132 +7067,14134 +7068,14136 +7069,14138 +7070,14140 +7071,14142 +7072,14144 +7073,14146 +7074,14148 +7075,14150 +7076,14152 +7077,14154 +7078,14156 +7079,14158 +7080,14160 +7081,14162 +7082,14164 +7083,14166 +7084,14168 +7085,14170 +7086,14172 +7087,14174 +7088,14176 +7089,14178 +7090,14180 +7091,14182 +7092,14184 +7093,14186 +7094,14188 +7095,14190 +7096,14192 +7097,14194 +7098,14196 +7099,14198 +7100,14200 +7101,14202 +7102,14204 +7103,14206 +7104,14208 +7105,14210 +7106,14212 +7107,14214 +7108,14216 +7109,14218 +7110,14220 +7111,14222 +7112,14224 +7113,14226 +7114,14228 +7115,14230 +7116,14232 +7117,14234 +7118,14236 +7119,14238 +7120,14240 +7121,14242 +7122,14244 +7123,14246 +7124,14248 +7125,14250 +7126,14252 +7127,14254 +7128,14256 +7129,14258 +7130,14260 +7131,14262 +7132,14264 +7133,14266 +7134,14268 +7135,14270 +7136,14272 +7137,14274 +7138,14276 +7139,14278 +7140,14280 +7141,14282 +7142,14284 +7143,14286 +7144,14288 +7145,14290 +7146,14292 +7147,14294 +7148,14296 +7149,14298 +7150,14300 +7151,14302 +7152,14304 +7153,14306 +7154,14308 +7155,14310 +7156,14312 +7157,14314 +7158,14316 +7159,14318 +7160,14320 +7161,14322 +7162,14324 +7163,14326 +7164,14328 +7165,14330 +7166,14332 +7167,14334 +7168,14336 +7169,14338 +7170,14340 +7171,14342 +7172,14344 +7173,14346 +7174,14348 +7175,14350 +7176,14352 +7177,14354 +7178,14356 +7179,14358 +7180,14360 +7181,14362 +7182,14364 +7183,14366 +7184,14368 +7185,14370 +7186,14372 +7187,14374 +7188,14376 +7189,14378 +7190,14380 +7191,14382 +7192,14384 +7193,14386 +7194,14388 +7195,14390 +7196,14392 +7197,14394 +7198,14396 +7199,14398 +7200,14400 +7201,14402 +7202,14404 +7203,14406 +7204,14408 +7205,14410 +7206,14412 +7207,14414 +7208,14416 +7209,14418 +7210,14420 +7211,14422 +7212,14424 +7213,14426 +7214,14428 +7215,14430 +7216,14432 +7217,14434 +7218,14436 +7219,14438 +7220,14440 +7221,14442 +7222,14444 +7223,14446 +7224,14448 +7225,14450 +7226,14452 +7227,14454 +7228,14456 +7229,14458 +7230,14460 +7231,14462 +7232,14464 +7233,14466 +7234,14468 +7235,14470 +7236,14472 +7237,14474 +7238,14476 +7239,14478 +7240,14480 +7241,14482 +7242,14484 +7243,14486 +7244,14488 +7245,14490 +7246,14492 +7247,14494 +7248,14496 +7249,14498 +7250,14500 +7251,14502 +7252,14504 +7253,14506 +7254,14508 +7255,14510 +7256,14512 +7257,14514 +7258,14516 +7259,14518 +7260,14520 +7261,14522 +7262,14524 +7263,14526 +7264,14528 +7265,14530 +7266,14532 +7267,14534 +7268,14536 +7269,14538 +7270,14540 +7271,14542 +7272,14544 +7273,14546 +7274,14548 +7275,14550 +7276,14552 +7277,14554 +7278,14556 +7279,14558 +7280,14560 +7281,14562 +7282,14564 +7283,14566 +7284,14568 +7285,14570 +7286,14572 +7287,14574 +7288,14576 +7289,14578 +7290,14580 +7291,14582 +7292,14584 +7293,14586 +7294,14588 +7295,14590 +7296,14592 +7297,14594 +7298,14596 +7299,14598 +7300,14600 +7301,14602 +7302,14604 +7303,14606 +7304,14608 +7305,14610 +7306,14612 +7307,14614 +7308,14616 +7309,14618 +7310,14620 +7311,14622 +7312,14624 +7313,14626 +7314,14628 +7315,14630 +7316,14632 +7317,14634 +7318,14636 +7319,14638 +7320,14640 +7321,14642 +7322,14644 +7323,14646 +7324,14648 +7325,14650 +7326,14652 +7327,14654 +7328,14656 +7329,14658 +7330,14660 +7331,14662 +7332,14664 +7333,14666 +7334,14668 +7335,14670 +7336,14672 +7337,14674 +7338,14676 +7339,14678 +7340,14680 +7341,14682 +7342,14684 +7343,14686 +7344,14688 +7345,14690 +7346,14692 +7347,14694 +7348,14696 +7349,14698 +7350,14700 +7351,14702 +7352,14704 +7353,14706 +7354,14708 +7355,14710 +7356,14712 +7357,14714 +7358,14716 +7359,14718 +7360,14720 +7361,14722 +7362,14724 +7363,14726 +7364,14728 +7365,14730 +7366,14732 +7367,14734 +7368,14736 +7369,14738 +7370,14740 +7371,14742 +7372,14744 +7373,14746 +7374,14748 +7375,14750 +7376,14752 +7377,14754 +7378,14756 +7379,14758 +7380,14760 +7381,14762 +7382,14764 +7383,14766 +7384,14768 +7385,14770 +7386,14772 +7387,14774 +7388,14776 +7389,14778 +7390,14780 +7391,14782 +7392,14784 +7393,14786 +7394,14788 +7395,14790 +7396,14792 +7397,14794 +7398,14796 +7399,14798 +7400,14800 +7401,14802 +7402,14804 +7403,14806 +7404,14808 +7405,14810 +7406,14812 +7407,14814 +7408,14816 +7409,14818 +7410,14820 +7411,14822 +7412,14824 +7413,14826 +7414,14828 +7415,14830 +7416,14832 +7417,14834 +7418,14836 +7419,14838 +7420,14840 +7421,14842 +7422,14844 +7423,14846 +7424,14848 +7425,14850 +7426,14852 +7427,14854 +7428,14856 +7429,14858 +7430,14860 +7431,14862 +7432,14864 +7433,14866 +7434,14868 +7435,14870 +7436,14872 +7437,14874 +7438,14876 +7439,14878 +7440,14880 +7441,14882 +7442,14884 +7443,14886 +7444,14888 +7445,14890 +7446,14892 +7447,14894 +7448,14896 +7449,14898 +7450,14900 +7451,14902 +7452,14904 +7453,14906 +7454,14908 +7455,14910 +7456,14912 +7457,14914 +7458,14916 +7459,14918 +7460,14920 +7461,14922 +7462,14924 +7463,14926 +7464,14928 +7465,14930 +7466,14932 +7467,14934 +7468,14936 +7469,14938 +7470,14940 +7471,14942 +7472,14944 +7473,14946 +7474,14948 +7475,14950 +7476,14952 +7477,14954 +7478,14956 +7479,14958 +7480,14960 +7481,14962 +7482,14964 +7483,14966 +7484,14968 +7485,14970 +7486,14972 +7487,14974 +7488,14976 +7489,14978 +7490,14980 +7491,14982 +7492,14984 +7493,14986 +7494,14988 +7495,14990 +7496,14992 +7497,14994 +7498,14996 +7499,14998 +7500,15000 +7501,15002 +7502,15004 +7503,15006 +7504,15008 +7505,15010 +7506,15012 +7507,15014 +7508,15016 +7509,15018 +7510,15020 +7511,15022 +7512,15024 +7513,15026 +7514,15028 +7515,15030 +7516,15032 +7517,15034 +7518,15036 +7519,15038 +7520,15040 +7521,15042 +7522,15044 +7523,15046 +7524,15048 +7525,15050 +7526,15052 +7527,15054 +7528,15056 +7529,15058 +7530,15060 +7531,15062 +7532,15064 +7533,15066 +7534,15068 +7535,15070 +7536,15072 +7537,15074 +7538,15076 +7539,15078 +7540,15080 +7541,15082 +7542,15084 +7543,15086 +7544,15088 +7545,15090 +7546,15092 +7547,15094 +7548,15096 +7549,15098 +7550,15100 +7551,15102 +7552,15104 +7553,15106 +7554,15108 +7555,15110 +7556,15112 +7557,15114 +7558,15116 +7559,15118 +7560,15120 +7561,15122 +7562,15124 +7563,15126 +7564,15128 +7565,15130 +7566,15132 +7567,15134 +7568,15136 +7569,15138 +7570,15140 +7571,15142 +7572,15144 +7573,15146 +7574,15148 +7575,15150 +7576,15152 +7577,15154 +7578,15156 +7579,15158 +7580,15160 +7581,15162 +7582,15164 +7583,15166 +7584,15168 +7585,15170 +7586,15172 +7587,15174 +7588,15176 +7589,15178 +7590,15180 +7591,15182 +7592,15184 +7593,15186 +7594,15188 +7595,15190 +7596,15192 +7597,15194 +7598,15196 +7599,15198 +7600,15200 +7601,15202 +7602,15204 +7603,15206 +7604,15208 +7605,15210 +7606,15212 +7607,15214 +7608,15216 +7609,15218 +7610,15220 +7611,15222 +7612,15224 +7613,15226 +7614,15228 +7615,15230 +7616,15232 +7617,15234 +7618,15236 +7619,15238 +7620,15240 +7621,15242 +7622,15244 +7623,15246 +7624,15248 +7625,15250 +7626,15252 +7627,15254 +7628,15256 +7629,15258 +7630,15260 +7631,15262 +7632,15264 +7633,15266 +7634,15268 +7635,15270 +7636,15272 +7637,15274 +7638,15276 +7639,15278 +7640,15280 +7641,15282 +7642,15284 +7643,15286 +7644,15288 +7645,15290 +7646,15292 +7647,15294 +7648,15296 +7649,15298 +7650,15300 +7651,15302 +7652,15304 +7653,15306 +7654,15308 +7655,15310 +7656,15312 +7657,15314 +7658,15316 +7659,15318 +7660,15320 +7661,15322 +7662,15324 +7663,15326 +7664,15328 +7665,15330 +7666,15332 +7667,15334 +7668,15336 +7669,15338 +7670,15340 +7671,15342 +7672,15344 +7673,15346 +7674,15348 +7675,15350 +7676,15352 +7677,15354 +7678,15356 +7679,15358 +7680,15360 +7681,15362 +7682,15364 +7683,15366 +7684,15368 +7685,15370 +7686,15372 +7687,15374 +7688,15376 +7689,15378 +7690,15380 +7691,15382 +7692,15384 +7693,15386 +7694,15388 +7695,15390 +7696,15392 +7697,15394 +7698,15396 +7699,15398 +7700,15400 +7701,15402 +7702,15404 +7703,15406 +7704,15408 +7705,15410 +7706,15412 +7707,15414 +7708,15416 +7709,15418 +7710,15420 +7711,15422 +7712,15424 +7713,15426 +7714,15428 +7715,15430 +7716,15432 +7717,15434 +7718,15436 +7719,15438 +7720,15440 +7721,15442 +7722,15444 +7723,15446 +7724,15448 +7725,15450 +7726,15452 +7727,15454 +7728,15456 +7729,15458 +7730,15460 +7731,15462 +7732,15464 +7733,15466 +7734,15468 +7735,15470 +7736,15472 +7737,15474 +7738,15476 +7739,15478 +7740,15480 +7741,15482 +7742,15484 +7743,15486 +7744,15488 +7745,15490 +7746,15492 +7747,15494 +7748,15496 +7749,15498 +7750,15500 +7751,15502 +7752,15504 +7753,15506 +7754,15508 +7755,15510 +7756,15512 +7757,15514 +7758,15516 +7759,15518 +7760,15520 +7761,15522 +7762,15524 +7763,15526 +7764,15528 +7765,15530 +7766,15532 +7767,15534 +7768,15536 +7769,15538 +7770,15540 +7771,15542 +7772,15544 +7773,15546 +7774,15548 +7775,15550 +7776,15552 +7777,15554 +7778,15556 +7779,15558 +7780,15560 +7781,15562 +7782,15564 +7783,15566 +7784,15568 +7785,15570 +7786,15572 +7787,15574 +7788,15576 +7789,15578 +7790,15580 +7791,15582 +7792,15584 +7793,15586 +7794,15588 +7795,15590 +7796,15592 +7797,15594 +7798,15596 +7799,15598 +7800,15600 +7801,15602 +7802,15604 +7803,15606 +7804,15608 +7805,15610 +7806,15612 +7807,15614 +7808,15616 +7809,15618 +7810,15620 +7811,15622 +7812,15624 +7813,15626 +7814,15628 +7815,15630 +7816,15632 +7817,15634 +7818,15636 +7819,15638 +7820,15640 +7821,15642 +7822,15644 +7823,15646 +7824,15648 +7825,15650 +7826,15652 +7827,15654 +7828,15656 +7829,15658 +7830,15660 +7831,15662 +7832,15664 +7833,15666 +7834,15668 +7835,15670 +7836,15672 +7837,15674 +7838,15676 +7839,15678 +7840,15680 +7841,15682 +7842,15684 +7843,15686 +7844,15688 +7845,15690 +7846,15692 +7847,15694 +7848,15696 +7849,15698 +7850,15700 +7851,15702 +7852,15704 +7853,15706 +7854,15708 +7855,15710 +7856,15712 +7857,15714 +7858,15716 +7859,15718 +7860,15720 +7861,15722 +7862,15724 +7863,15726 +7864,15728 +7865,15730 +7866,15732 +7867,15734 +7868,15736 +7869,15738 +7870,15740 +7871,15742 +7872,15744 +7873,15746 +7874,15748 +7875,15750 +7876,15752 +7877,15754 +7878,15756 +7879,15758 +7880,15760 +7881,15762 +7882,15764 +7883,15766 +7884,15768 +7885,15770 +7886,15772 +7887,15774 +7888,15776 +7889,15778 +7890,15780 +7891,15782 +7892,15784 +7893,15786 +7894,15788 +7895,15790 +7896,15792 +7897,15794 +7898,15796 +7899,15798 +7900,15800 +7901,15802 +7902,15804 +7903,15806 +7904,15808 +7905,15810 +7906,15812 +7907,15814 +7908,15816 +7909,15818 +7910,15820 +7911,15822 +7912,15824 +7913,15826 +7914,15828 +7915,15830 +7916,15832 +7917,15834 +7918,15836 +7919,15838 +7920,15840 +7921,15842 +7922,15844 +7923,15846 +7924,15848 +7925,15850 +7926,15852 +7927,15854 +7928,15856 +7929,15858 +7930,15860 +7931,15862 +7932,15864 +7933,15866 +7934,15868 +7935,15870 +7936,15872 +7937,15874 +7938,15876 +7939,15878 +7940,15880 +7941,15882 +7942,15884 +7943,15886 +7944,15888 +7945,15890 +7946,15892 +7947,15894 +7948,15896 +7949,15898 +7950,15900 +7951,15902 +7952,15904 +7953,15906 +7954,15908 +7955,15910 +7956,15912 +7957,15914 +7958,15916 +7959,15918 +7960,15920 +7961,15922 +7962,15924 +7963,15926 +7964,15928 +7965,15930 +7966,15932 +7967,15934 +7968,15936 +7969,15938 +7970,15940 +7971,15942 +7972,15944 +7973,15946 +7974,15948 +7975,15950 +7976,15952 +7977,15954 +7978,15956 +7979,15958 +7980,15960 +7981,15962 +7982,15964 +7983,15966 +7984,15968 +7985,15970 +7986,15972 +7987,15974 +7988,15976 +7989,15978 +7990,15980 +7991,15982 +7992,15984 +7993,15986 +7994,15988 +7995,15990 +7996,15992 +7997,15994 +7998,15996 +7999,15998 +8000,16000 +8001,16002 +8002,16004 +8003,16006 +8004,16008 +8005,16010 +8006,16012 +8007,16014 +8008,16016 +8009,16018 +8010,16020 +8011,16022 +8012,16024 +8013,16026 +8014,16028 +8015,16030 +8016,16032 +8017,16034 +8018,16036 +8019,16038 +8020,16040 +8021,16042 +8022,16044 +8023,16046 +8024,16048 +8025,16050 +8026,16052 +8027,16054 +8028,16056 +8029,16058 +8030,16060 +8031,16062 +8032,16064 +8033,16066 +8034,16068 +8035,16070 +8036,16072 +8037,16074 +8038,16076 +8039,16078 +8040,16080 +8041,16082 +8042,16084 +8043,16086 +8044,16088 +8045,16090 +8046,16092 +8047,16094 +8048,16096 +8049,16098 +8050,16100 +8051,16102 +8052,16104 +8053,16106 +8054,16108 +8055,16110 +8056,16112 +8057,16114 +8058,16116 +8059,16118 +8060,16120 +8061,16122 +8062,16124 +8063,16126 +8064,16128 +8065,16130 +8066,16132 +8067,16134 +8068,16136 +8069,16138 +8070,16140 +8071,16142 +8072,16144 +8073,16146 +8074,16148 +8075,16150 +8076,16152 +8077,16154 +8078,16156 +8079,16158 +8080,16160 +8081,16162 +8082,16164 +8083,16166 +8084,16168 +8085,16170 +8086,16172 +8087,16174 +8088,16176 +8089,16178 +8090,16180 +8091,16182 +8092,16184 +8093,16186 +8094,16188 +8095,16190 +8096,16192 +8097,16194 +8098,16196 +8099,16198 +8100,16200 +8101,16202 +8102,16204 +8103,16206 +8104,16208 +8105,16210 +8106,16212 +8107,16214 +8108,16216 +8109,16218 +8110,16220 +8111,16222 +8112,16224 +8113,16226 +8114,16228 +8115,16230 +8116,16232 +8117,16234 +8118,16236 +8119,16238 +8120,16240 +8121,16242 +8122,16244 +8123,16246 +8124,16248 +8125,16250 +8126,16252 +8127,16254 +8128,16256 +8129,16258 +8130,16260 +8131,16262 +8132,16264 +8133,16266 +8134,16268 +8135,16270 +8136,16272 +8137,16274 +8138,16276 +8139,16278 +8140,16280 +8141,16282 +8142,16284 +8143,16286 +8144,16288 +8145,16290 +8146,16292 +8147,16294 +8148,16296 +8149,16298 +8150,16300 +8151,16302 +8152,16304 +8153,16306 +8154,16308 +8155,16310 +8156,16312 +8157,16314 +8158,16316 +8159,16318 +8160,16320 +8161,16322 +8162,16324 +8163,16326 +8164,16328 +8165,16330 +8166,16332 +8167,16334 +8168,16336 +8169,16338 +8170,16340 +8171,16342 +8172,16344 +8173,16346 +8174,16348 +8175,16350 +8176,16352 +8177,16354 +8178,16356 +8179,16358 +8180,16360 +8181,16362 +8182,16364 +8183,16366 +8184,16368 +8185,16370 +8186,16372 +8187,16374 +8188,16376 +8189,16378 +8190,16380 +8191,16382 +8192,16384 +8193,16386 +8194,16388 +8195,16390 +8196,16392 +8197,16394 +8198,16396 +8199,16398 +8200,16400 +8201,16402 +8202,16404 +8203,16406 +8204,16408 +8205,16410 +8206,16412 +8207,16414 +8208,16416 +8209,16418 +8210,16420 +8211,16422 +8212,16424 +8213,16426 +8214,16428 +8215,16430 +8216,16432 +8217,16434 +8218,16436 +8219,16438 +8220,16440 +8221,16442 +8222,16444 +8223,16446 +8224,16448 +8225,16450 +8226,16452 +8227,16454 +8228,16456 +8229,16458 +8230,16460 +8231,16462 +8232,16464 +8233,16466 +8234,16468 +8235,16470 +8236,16472 +8237,16474 +8238,16476 +8239,16478 +8240,16480 +8241,16482 +8242,16484 +8243,16486 +8244,16488 +8245,16490 +8246,16492 +8247,16494 +8248,16496 +8249,16498 +8250,16500 +8251,16502 +8252,16504 +8253,16506 +8254,16508 +8255,16510 +8256,16512 +8257,16514 +8258,16516 +8259,16518 +8260,16520 +8261,16522 +8262,16524 +8263,16526 +8264,16528 +8265,16530 +8266,16532 +8267,16534 +8268,16536 +8269,16538 +8270,16540 +8271,16542 +8272,16544 +8273,16546 +8274,16548 +8275,16550 +8276,16552 +8277,16554 +8278,16556 +8279,16558 +8280,16560 +8281,16562 +8282,16564 +8283,16566 +8284,16568 +8285,16570 +8286,16572 +8287,16574 +8288,16576 +8289,16578 +8290,16580 +8291,16582 +8292,16584 +8293,16586 +8294,16588 +8295,16590 +8296,16592 +8297,16594 +8298,16596 +8299,16598 +8300,16600 +8301,16602 +8302,16604 +8303,16606 +8304,16608 +8305,16610 +8306,16612 +8307,16614 +8308,16616 +8309,16618 +8310,16620 +8311,16622 +8312,16624 +8313,16626 +8314,16628 +8315,16630 +8316,16632 +8317,16634 +8318,16636 +8319,16638 +8320,16640 +8321,16642 +8322,16644 +8323,16646 +8324,16648 +8325,16650 +8326,16652 +8327,16654 +8328,16656 +8329,16658 +8330,16660 +8331,16662 +8332,16664 +8333,16666 +8334,16668 +8335,16670 +8336,16672 +8337,16674 +8338,16676 +8339,16678 +8340,16680 +8341,16682 +8342,16684 +8343,16686 +8344,16688 +8345,16690 +8346,16692 +8347,16694 +8348,16696 +8349,16698 +8350,16700 +8351,16702 +8352,16704 +8353,16706 +8354,16708 +8355,16710 +8356,16712 +8357,16714 +8358,16716 +8359,16718 +8360,16720 +8361,16722 +8362,16724 +8363,16726 +8364,16728 +8365,16730 +8366,16732 +8367,16734 +8368,16736 +8369,16738 +8370,16740 +8371,16742 +8372,16744 +8373,16746 +8374,16748 +8375,16750 +8376,16752 +8377,16754 +8378,16756 +8379,16758 +8380,16760 +8381,16762 +8382,16764 +8383,16766 +8384,16768 +8385,16770 +8386,16772 +8387,16774 +8388,16776 +8389,16778 +8390,16780 +8391,16782 +8392,16784 +8393,16786 +8394,16788 +8395,16790 +8396,16792 +8397,16794 +8398,16796 +8399,16798 +8400,16800 +8401,16802 +8402,16804 +8403,16806 +8404,16808 +8405,16810 +8406,16812 +8407,16814 +8408,16816 +8409,16818 +8410,16820 +8411,16822 +8412,16824 +8413,16826 +8414,16828 +8415,16830 +8416,16832 +8417,16834 +8418,16836 +8419,16838 +8420,16840 +8421,16842 +8422,16844 +8423,16846 +8424,16848 +8425,16850 +8426,16852 +8427,16854 +8428,16856 +8429,16858 +8430,16860 +8431,16862 +8432,16864 +8433,16866 +8434,16868 +8435,16870 +8436,16872 +8437,16874 +8438,16876 +8439,16878 +8440,16880 +8441,16882 +8442,16884 +8443,16886 +8444,16888 +8445,16890 +8446,16892 +8447,16894 +8448,16896 +8449,16898 +8450,16900 +8451,16902 +8452,16904 +8453,16906 +8454,16908 +8455,16910 +8456,16912 +8457,16914 +8458,16916 +8459,16918 +8460,16920 +8461,16922 +8462,16924 +8463,16926 +8464,16928 +8465,16930 +8466,16932 +8467,16934 +8468,16936 +8469,16938 +8470,16940 +8471,16942 +8472,16944 +8473,16946 +8474,16948 +8475,16950 +8476,16952 +8477,16954 +8478,16956 +8479,16958 +8480,16960 +8481,16962 +8482,16964 +8483,16966 +8484,16968 +8485,16970 +8486,16972 +8487,16974 +8488,16976 +8489,16978 +8490,16980 +8491,16982 +8492,16984 +8493,16986 +8494,16988 +8495,16990 +8496,16992 +8497,16994 +8498,16996 +8499,16998 +8500,17000 +8501,17002 +8502,17004 +8503,17006 +8504,17008 +8505,17010 +8506,17012 +8507,17014 +8508,17016 +8509,17018 +8510,17020 +8511,17022 +8512,17024 +8513,17026 +8514,17028 +8515,17030 +8516,17032 +8517,17034 +8518,17036 +8519,17038 +8520,17040 +8521,17042 +8522,17044 +8523,17046 +8524,17048 +8525,17050 +8526,17052 +8527,17054 +8528,17056 +8529,17058 +8530,17060 +8531,17062 +8532,17064 +8533,17066 +8534,17068 +8535,17070 +8536,17072 +8537,17074 +8538,17076 +8539,17078 +8540,17080 +8541,17082 +8542,17084 +8543,17086 +8544,17088 +8545,17090 +8546,17092 +8547,17094 +8548,17096 +8549,17098 +8550,17100 +8551,17102 +8552,17104 +8553,17106 +8554,17108 +8555,17110 +8556,17112 +8557,17114 +8558,17116 +8559,17118 +8560,17120 +8561,17122 +8562,17124 +8563,17126 +8564,17128 +8565,17130 +8566,17132 +8567,17134 +8568,17136 +8569,17138 +8570,17140 +8571,17142 +8572,17144 +8573,17146 +8574,17148 +8575,17150 +8576,17152 +8577,17154 +8578,17156 +8579,17158 +8580,17160 +8581,17162 +8582,17164 +8583,17166 +8584,17168 +8585,17170 +8586,17172 +8587,17174 +8588,17176 +8589,17178 +8590,17180 +8591,17182 +8592,17184 +8593,17186 +8594,17188 +8595,17190 +8596,17192 +8597,17194 +8598,17196 +8599,17198 +8600,17200 +8601,17202 +8602,17204 +8603,17206 +8604,17208 +8605,17210 +8606,17212 +8607,17214 +8608,17216 +8609,17218 +8610,17220 +8611,17222 +8612,17224 +8613,17226 +8614,17228 +8615,17230 +8616,17232 +8617,17234 +8618,17236 +8619,17238 +8620,17240 +8621,17242 +8622,17244 +8623,17246 +8624,17248 +8625,17250 +8626,17252 +8627,17254 +8628,17256 +8629,17258 +8630,17260 +8631,17262 +8632,17264 +8633,17266 +8634,17268 +8635,17270 +8636,17272 +8637,17274 +8638,17276 +8639,17278 +8640,17280 +8641,17282 +8642,17284 +8643,17286 +8644,17288 +8645,17290 +8646,17292 +8647,17294 +8648,17296 +8649,17298 +8650,17300 +8651,17302 +8652,17304 +8653,17306 +8654,17308 +8655,17310 +8656,17312 +8657,17314 +8658,17316 +8659,17318 +8660,17320 +8661,17322 +8662,17324 +8663,17326 +8664,17328 +8665,17330 +8666,17332 +8667,17334 +8668,17336 +8669,17338 +8670,17340 +8671,17342 +8672,17344 +8673,17346 +8674,17348 +8675,17350 +8676,17352 +8677,17354 +8678,17356 +8679,17358 +8680,17360 +8681,17362 +8682,17364 +8683,17366 +8684,17368 +8685,17370 +8686,17372 +8687,17374 +8688,17376 +8689,17378 +8690,17380 +8691,17382 +8692,17384 +8693,17386 +8694,17388 +8695,17390 +8696,17392 +8697,17394 +8698,17396 +8699,17398 +8700,17400 +8701,17402 +8702,17404 +8703,17406 +8704,17408 +8705,17410 +8706,17412 +8707,17414 +8708,17416 +8709,17418 +8710,17420 +8711,17422 +8712,17424 +8713,17426 +8714,17428 +8715,17430 +8716,17432 +8717,17434 +8718,17436 +8719,17438 +8720,17440 +8721,17442 +8722,17444 +8723,17446 +8724,17448 +8725,17450 +8726,17452 +8727,17454 +8728,17456 +8729,17458 +8730,17460 +8731,17462 +8732,17464 +8733,17466 +8734,17468 +8735,17470 +8736,17472 +8737,17474 +8738,17476 +8739,17478 +8740,17480 +8741,17482 +8742,17484 +8743,17486 +8744,17488 +8745,17490 +8746,17492 +8747,17494 +8748,17496 +8749,17498 +8750,17500 +8751,17502 +8752,17504 +8753,17506 +8754,17508 +8755,17510 +8756,17512 +8757,17514 +8758,17516 +8759,17518 +8760,17520 +8761,17522 +8762,17524 +8763,17526 +8764,17528 +8765,17530 +8766,17532 +8767,17534 +8768,17536 +8769,17538 +8770,17540 +8771,17542 +8772,17544 +8773,17546 +8774,17548 +8775,17550 +8776,17552 +8777,17554 +8778,17556 +8779,17558 +8780,17560 +8781,17562 +8782,17564 +8783,17566 +8784,17568 +8785,17570 +8786,17572 +8787,17574 +8788,17576 +8789,17578 +8790,17580 +8791,17582 +8792,17584 +8793,17586 +8794,17588 +8795,17590 +8796,17592 +8797,17594 +8798,17596 +8799,17598 +8800,17600 +8801,17602 +8802,17604 +8803,17606 +8804,17608 +8805,17610 +8806,17612 +8807,17614 +8808,17616 +8809,17618 +8810,17620 +8811,17622 +8812,17624 +8813,17626 +8814,17628 +8815,17630 +8816,17632 +8817,17634 +8818,17636 +8819,17638 +8820,17640 +8821,17642 +8822,17644 +8823,17646 +8824,17648 +8825,17650 +8826,17652 +8827,17654 +8828,17656 +8829,17658 +8830,17660 +8831,17662 +8832,17664 +8833,17666 +8834,17668 +8835,17670 +8836,17672 +8837,17674 +8838,17676 +8839,17678 +8840,17680 +8841,17682 +8842,17684 +8843,17686 +8844,17688 +8845,17690 +8846,17692 +8847,17694 +8848,17696 +8849,17698 +8850,17700 +8851,17702 +8852,17704 +8853,17706 +8854,17708 +8855,17710 +8856,17712 +8857,17714 +8858,17716 +8859,17718 +8860,17720 +8861,17722 +8862,17724 +8863,17726 +8864,17728 +8865,17730 +8866,17732 +8867,17734 +8868,17736 +8869,17738 +8870,17740 +8871,17742 +8872,17744 +8873,17746 +8874,17748 +8875,17750 +8876,17752 +8877,17754 +8878,17756 +8879,17758 +8880,17760 +8881,17762 +8882,17764 +8883,17766 +8884,17768 +8885,17770 +8886,17772 +8887,17774 +8888,17776 +8889,17778 +8890,17780 +8891,17782 +8892,17784 +8893,17786 +8894,17788 +8895,17790 +8896,17792 +8897,17794 +8898,17796 +8899,17798 +8900,17800 +8901,17802 +8902,17804 +8903,17806 +8904,17808 +8905,17810 +8906,17812 +8907,17814 +8908,17816 +8909,17818 +8910,17820 +8911,17822 +8912,17824 +8913,17826 +8914,17828 +8915,17830 +8916,17832 +8917,17834 +8918,17836 +8919,17838 +8920,17840 +8921,17842 +8922,17844 +8923,17846 +8924,17848 +8925,17850 +8926,17852 +8927,17854 +8928,17856 +8929,17858 +8930,17860 +8931,17862 +8932,17864 +8933,17866 +8934,17868 +8935,17870 +8936,17872 +8937,17874 +8938,17876 +8939,17878 +8940,17880 +8941,17882 +8942,17884 +8943,17886 +8944,17888 +8945,17890 +8946,17892 +8947,17894 +8948,17896 +8949,17898 +8950,17900 +8951,17902 +8952,17904 +8953,17906 +8954,17908 +8955,17910 +8956,17912 +8957,17914 +8958,17916 +8959,17918 +8960,17920 +8961,17922 +8962,17924 +8963,17926 +8964,17928 +8965,17930 +8966,17932 +8967,17934 +8968,17936 +8969,17938 +8970,17940 +8971,17942 +8972,17944 +8973,17946 +8974,17948 +8975,17950 +8976,17952 +8977,17954 +8978,17956 +8979,17958 +8980,17960 +8981,17962 +8982,17964 +8983,17966 +8984,17968 +8985,17970 +8986,17972 +8987,17974 +8988,17976 +8989,17978 +8990,17980 +8991,17982 +8992,17984 +8993,17986 +8994,17988 +8995,17990 +8996,17992 +8997,17994 +8998,17996 +8999,17998 +9000,18000 +9001,18002 +9002,18004 +9003,18006 +9004,18008 +9005,18010 +9006,18012 +9007,18014 +9008,18016 +9009,18018 +9010,18020 +9011,18022 +9012,18024 +9013,18026 +9014,18028 +9015,18030 +9016,18032 +9017,18034 +9018,18036 +9019,18038 +9020,18040 +9021,18042 +9022,18044 +9023,18046 +9024,18048 +9025,18050 +9026,18052 +9027,18054 +9028,18056 +9029,18058 +9030,18060 +9031,18062 +9032,18064 +9033,18066 +9034,18068 +9035,18070 +9036,18072 +9037,18074 +9038,18076 +9039,18078 +9040,18080 +9041,18082 +9042,18084 +9043,18086 +9044,18088 +9045,18090 +9046,18092 +9047,18094 +9048,18096 +9049,18098 +9050,18100 +9051,18102 +9052,18104 +9053,18106 +9054,18108 +9055,18110 +9056,18112 +9057,18114 +9058,18116 +9059,18118 +9060,18120 +9061,18122 +9062,18124 +9063,18126 +9064,18128 +9065,18130 +9066,18132 +9067,18134 +9068,18136 +9069,18138 +9070,18140 +9071,18142 +9072,18144 +9073,18146 +9074,18148 +9075,18150 +9076,18152 +9077,18154 +9078,18156 +9079,18158 +9080,18160 +9081,18162 +9082,18164 +9083,18166 +9084,18168 +9085,18170 +9086,18172 +9087,18174 +9088,18176 +9089,18178 +9090,18180 +9091,18182 +9092,18184 +9093,18186 +9094,18188 +9095,18190 +9096,18192 +9097,18194 +9098,18196 +9099,18198 +9100,18200 +9101,18202 +9102,18204 +9103,18206 +9104,18208 +9105,18210 +9106,18212 +9107,18214 +9108,18216 +9109,18218 +9110,18220 +9111,18222 +9112,18224 +9113,18226 +9114,18228 +9115,18230 +9116,18232 +9117,18234 +9118,18236 +9119,18238 +9120,18240 +9121,18242 +9122,18244 +9123,18246 +9124,18248 +9125,18250 +9126,18252 +9127,18254 +9128,18256 +9129,18258 +9130,18260 +9131,18262 +9132,18264 +9133,18266 +9134,18268 +9135,18270 +9136,18272 +9137,18274 +9138,18276 +9139,18278 +9140,18280 +9141,18282 +9142,18284 +9143,18286 +9144,18288 +9145,18290 +9146,18292 +9147,18294 +9148,18296 +9149,18298 +9150,18300 +9151,18302 +9152,18304 +9153,18306 +9154,18308 +9155,18310 +9156,18312 +9157,18314 +9158,18316 +9159,18318 +9160,18320 +9161,18322 +9162,18324 +9163,18326 +9164,18328 +9165,18330 +9166,18332 +9167,18334 +9168,18336 +9169,18338 +9170,18340 +9171,18342 +9172,18344 +9173,18346 +9174,18348 +9175,18350 +9176,18352 +9177,18354 +9178,18356 +9179,18358 +9180,18360 +9181,18362 +9182,18364 +9183,18366 +9184,18368 +9185,18370 +9186,18372 +9187,18374 +9188,18376 +9189,18378 +9190,18380 +9191,18382 +9192,18384 +9193,18386 +9194,18388 +9195,18390 +9196,18392 +9197,18394 +9198,18396 +9199,18398 +9200,18400 +9201,18402 +9202,18404 +9203,18406 +9204,18408 +9205,18410 +9206,18412 +9207,18414 +9208,18416 +9209,18418 +9210,18420 +9211,18422 +9212,18424 +9213,18426 +9214,18428 +9215,18430 +9216,18432 +9217,18434 +9218,18436 +9219,18438 +9220,18440 +9221,18442 +9222,18444 +9223,18446 +9224,18448 +9225,18450 +9226,18452 +9227,18454 +9228,18456 +9229,18458 +9230,18460 +9231,18462 +9232,18464 +9233,18466 +9234,18468 +9235,18470 +9236,18472 +9237,18474 +9238,18476 +9239,18478 +9240,18480 +9241,18482 +9242,18484 +9243,18486 +9244,18488 +9245,18490 +9246,18492 +9247,18494 +9248,18496 +9249,18498 +9250,18500 +9251,18502 +9252,18504 +9253,18506 +9254,18508 +9255,18510 +9256,18512 +9257,18514 +9258,18516 +9259,18518 +9260,18520 +9261,18522 +9262,18524 +9263,18526 +9264,18528 +9265,18530 +9266,18532 +9267,18534 +9268,18536 +9269,18538 +9270,18540 +9271,18542 +9272,18544 +9273,18546 +9274,18548 +9275,18550 +9276,18552 +9277,18554 +9278,18556 +9279,18558 +9280,18560 +9281,18562 +9282,18564 +9283,18566 +9284,18568 +9285,18570 +9286,18572 +9287,18574 +9288,18576 +9289,18578 +9290,18580 +9291,18582 +9292,18584 +9293,18586 +9294,18588 +9295,18590 +9296,18592 +9297,18594 +9298,18596 +9299,18598 +9300,18600 +9301,18602 +9302,18604 +9303,18606 +9304,18608 +9305,18610 +9306,18612 +9307,18614 +9308,18616 +9309,18618 +9310,18620 +9311,18622 +9312,18624 +9313,18626 +9314,18628 +9315,18630 +9316,18632 +9317,18634 +9318,18636 +9319,18638 +9320,18640 +9321,18642 +9322,18644 +9323,18646 +9324,18648 +9325,18650 +9326,18652 +9327,18654 +9328,18656 +9329,18658 +9330,18660 +9331,18662 +9332,18664 +9333,18666 +9334,18668 +9335,18670 +9336,18672 +9337,18674 +9338,18676 +9339,18678 +9340,18680 +9341,18682 +9342,18684 +9343,18686 +9344,18688 +9345,18690 +9346,18692 +9347,18694 +9348,18696 +9349,18698 +9350,18700 +9351,18702 +9352,18704 +9353,18706 +9354,18708 +9355,18710 +9356,18712 +9357,18714 +9358,18716 +9359,18718 +9360,18720 +9361,18722 +9362,18724 +9363,18726 +9364,18728 +9365,18730 +9366,18732 +9367,18734 +9368,18736 +9369,18738 +9370,18740 +9371,18742 +9372,18744 +9373,18746 +9374,18748 +9375,18750 +9376,18752 +9377,18754 +9378,18756 +9379,18758 +9380,18760 +9381,18762 +9382,18764 +9383,18766 +9384,18768 +9385,18770 +9386,18772 +9387,18774 +9388,18776 +9389,18778 +9390,18780 +9391,18782 +9392,18784 +9393,18786 +9394,18788 +9395,18790 +9396,18792 +9397,18794 +9398,18796 +9399,18798 +9400,18800 +9401,18802 +9402,18804 +9403,18806 +9404,18808 +9405,18810 +9406,18812 +9407,18814 +9408,18816 +9409,18818 +9410,18820 +9411,18822 +9412,18824 +9413,18826 +9414,18828 +9415,18830 +9416,18832 +9417,18834 +9418,18836 +9419,18838 +9420,18840 +9421,18842 +9422,18844 +9423,18846 +9424,18848 +9425,18850 +9426,18852 +9427,18854 +9428,18856 +9429,18858 +9430,18860 +9431,18862 +9432,18864 +9433,18866 +9434,18868 +9435,18870 +9436,18872 +9437,18874 +9438,18876 +9439,18878 +9440,18880 +9441,18882 +9442,18884 +9443,18886 +9444,18888 +9445,18890 +9446,18892 +9447,18894 +9448,18896 +9449,18898 +9450,18900 +9451,18902 +9452,18904 +9453,18906 +9454,18908 +9455,18910 +9456,18912 +9457,18914 +9458,18916 +9459,18918 +9460,18920 +9461,18922 +9462,18924 +9463,18926 +9464,18928 +9465,18930 +9466,18932 +9467,18934 +9468,18936 +9469,18938 +9470,18940 +9471,18942 +9472,18944 +9473,18946 +9474,18948 +9475,18950 +9476,18952 +9477,18954 +9478,18956 +9479,18958 +9480,18960 +9481,18962 +9482,18964 +9483,18966 +9484,18968 +9485,18970 +9486,18972 +9487,18974 +9488,18976 +9489,18978 +9490,18980 +9491,18982 +9492,18984 +9493,18986 +9494,18988 +9495,18990 +9496,18992 +9497,18994 +9498,18996 +9499,18998 +9500,19000 +9501,19002 +9502,19004 +9503,19006 +9504,19008 +9505,19010 +9506,19012 +9507,19014 +9508,19016 +9509,19018 +9510,19020 +9511,19022 +9512,19024 +9513,19026 +9514,19028 +9515,19030 +9516,19032 +9517,19034 +9518,19036 +9519,19038 +9520,19040 +9521,19042 +9522,19044 +9523,19046 +9524,19048 +9525,19050 +9526,19052 +9527,19054 +9528,19056 +9529,19058 +9530,19060 +9531,19062 +9532,19064 +9533,19066 +9534,19068 +9535,19070 +9536,19072 +9537,19074 +9538,19076 +9539,19078 +9540,19080 +9541,19082 +9542,19084 +9543,19086 +9544,19088 +9545,19090 +9546,19092 +9547,19094 +9548,19096 +9549,19098 +9550,19100 +9551,19102 +9552,19104 +9553,19106 +9554,19108 +9555,19110 +9556,19112 +9557,19114 +9558,19116 +9559,19118 +9560,19120 +9561,19122 +9562,19124 +9563,19126 +9564,19128 +9565,19130 +9566,19132 +9567,19134 +9568,19136 +9569,19138 +9570,19140 +9571,19142 +9572,19144 +9573,19146 +9574,19148 +9575,19150 +9576,19152 +9577,19154 +9578,19156 +9579,19158 +9580,19160 +9581,19162 +9582,19164 +9583,19166 +9584,19168 +9585,19170 +9586,19172 +9587,19174 +9588,19176 +9589,19178 +9590,19180 +9591,19182 +9592,19184 +9593,19186 +9594,19188 +9595,19190 +9596,19192 +9597,19194 +9598,19196 +9599,19198 +9600,19200 +9601,19202 +9602,19204 +9603,19206 +9604,19208 +9605,19210 +9606,19212 +9607,19214 +9608,19216 +9609,19218 +9610,19220 +9611,19222 +9612,19224 +9613,19226 +9614,19228 +9615,19230 +9616,19232 +9617,19234 +9618,19236 +9619,19238 +9620,19240 +9621,19242 +9622,19244 +9623,19246 +9624,19248 +9625,19250 +9626,19252 +9627,19254 +9628,19256 +9629,19258 +9630,19260 +9631,19262 +9632,19264 +9633,19266 +9634,19268 +9635,19270 +9636,19272 +9637,19274 +9638,19276 +9639,19278 +9640,19280 +9641,19282 +9642,19284 +9643,19286 +9644,19288 +9645,19290 +9646,19292 +9647,19294 +9648,19296 +9649,19298 +9650,19300 +9651,19302 +9652,19304 +9653,19306 +9654,19308 +9655,19310 +9656,19312 +9657,19314 +9658,19316 +9659,19318 +9660,19320 +9661,19322 +9662,19324 +9663,19326 +9664,19328 +9665,19330 +9666,19332 +9667,19334 +9668,19336 +9669,19338 +9670,19340 +9671,19342 +9672,19344 +9673,19346 +9674,19348 +9675,19350 +9676,19352 +9677,19354 +9678,19356 +9679,19358 +9680,19360 +9681,19362 +9682,19364 +9683,19366 +9684,19368 +9685,19370 +9686,19372 +9687,19374 +9688,19376 +9689,19378 +9690,19380 +9691,19382 +9692,19384 +9693,19386 +9694,19388 +9695,19390 +9696,19392 +9697,19394 +9698,19396 +9699,19398 +9700,19400 +9701,19402 +9702,19404 +9703,19406 +9704,19408 +9705,19410 +9706,19412 +9707,19414 +9708,19416 +9709,19418 +9710,19420 +9711,19422 +9712,19424 +9713,19426 +9714,19428 +9715,19430 +9716,19432 +9717,19434 +9718,19436 +9719,19438 +9720,19440 +9721,19442 +9722,19444 +9723,19446 +9724,19448 +9725,19450 +9726,19452 +9727,19454 +9728,19456 +9729,19458 +9730,19460 +9731,19462 +9732,19464 +9733,19466 +9734,19468 +9735,19470 +9736,19472 +9737,19474 +9738,19476 +9739,19478 +9740,19480 +9741,19482 +9742,19484 +9743,19486 +9744,19488 +9745,19490 +9746,19492 +9747,19494 +9748,19496 +9749,19498 +9750,19500 +9751,19502 +9752,19504 +9753,19506 +9754,19508 +9755,19510 +9756,19512 +9757,19514 +9758,19516 +9759,19518 +9760,19520 +9761,19522 +9762,19524 +9763,19526 +9764,19528 +9765,19530 +9766,19532 +9767,19534 +9768,19536 +9769,19538 +9770,19540 +9771,19542 +9772,19544 +9773,19546 +9774,19548 +9775,19550 +9776,19552 +9777,19554 +9778,19556 +9779,19558 +9780,19560 +9781,19562 +9782,19564 +9783,19566 +9784,19568 +9785,19570 +9786,19572 +9787,19574 +9788,19576 +9789,19578 +9790,19580 +9791,19582 +9792,19584 +9793,19586 +9794,19588 +9795,19590 +9796,19592 +9797,19594 +9798,19596 +9799,19598 +9800,19600 +9801,19602 +9802,19604 +9803,19606 +9804,19608 +9805,19610 +9806,19612 +9807,19614 +9808,19616 +9809,19618 +9810,19620 +9811,19622 +9812,19624 +9813,19626 +9814,19628 +9815,19630 +9816,19632 +9817,19634 +9818,19636 +9819,19638 +9820,19640 +9821,19642 +9822,19644 +9823,19646 +9824,19648 +9825,19650 +9826,19652 +9827,19654 +9828,19656 +9829,19658 +9830,19660 +9831,19662 +9832,19664 +9833,19666 +9834,19668 +9835,19670 +9836,19672 +9837,19674 +9838,19676 +9839,19678 +9840,19680 +9841,19682 +9842,19684 +9843,19686 +9844,19688 +9845,19690 +9846,19692 +9847,19694 +9848,19696 +9849,19698 +9850,19700 +9851,19702 +9852,19704 +9853,19706 +9854,19708 +9855,19710 +9856,19712 +9857,19714 +9858,19716 +9859,19718 +9860,19720 +9861,19722 +9862,19724 +9863,19726 +9864,19728 +9865,19730 +9866,19732 +9867,19734 +9868,19736 +9869,19738 +9870,19740 +9871,19742 +9872,19744 +9873,19746 +9874,19748 +9875,19750 +9876,19752 +9877,19754 +9878,19756 +9879,19758 +9880,19760 +9881,19762 +9882,19764 +9883,19766 +9884,19768 +9885,19770 +9886,19772 +9887,19774 +9888,19776 +9889,19778 +9890,19780 +9891,19782 +9892,19784 +9893,19786 +9894,19788 +9895,19790 +9896,19792 +9897,19794 +9898,19796 +9899,19798 +9900,19800 +9901,19802 +9902,19804 +9903,19806 +9904,19808 +9905,19810 +9906,19812 +9907,19814 +9908,19816 +9909,19818 +9910,19820 +9911,19822 +9912,19824 +9913,19826 +9914,19828 +9915,19830 +9916,19832 +9917,19834 +9918,19836 +9919,19838 +9920,19840 +9921,19842 +9922,19844 +9923,19846 +9924,19848 +9925,19850 +9926,19852 +9927,19854 +9928,19856 +9929,19858 +9930,19860 +9931,19862 +9932,19864 +9933,19866 +9934,19868 +9935,19870 +9936,19872 +9937,19874 +9938,19876 +9939,19878 +9940,19880 +9941,19882 +9942,19884 +9943,19886 +9944,19888 +9945,19890 +9946,19892 +9947,19894 +9948,19896 +9949,19898 +9950,19900 +9951,19902 +9952,19904 +9953,19906 +9954,19908 +9955,19910 +9956,19912 +9957,19914 +9958,19916 +9959,19918 +9960,19920 +9961,19922 +9962,19924 +9963,19926 +9964,19928 +9965,19930 +9966,19932 +9967,19934 +9968,19936 +9969,19938 +9970,19940 +9971,19942 +9972,19944 +9973,19946 +9974,19948 +9975,19950 +9976,19952 +9977,19954 +9978,19956 +9979,19958 +9980,19960 +9981,19962 +9982,19964 +9983,19966 +9984,19968 +9985,19970 +9986,19972 +9987,19974 +9988,19976 +9989,19978 +9990,19980 +9991,19982 +9992,19984 +9993,19986 +9994,19988 +9995,19990 +9996,19992 +9997,19994 +9998,19996 +9999,19998 +10000,20000 \ No newline at end of file diff --git a/regression-test/data/data_model_p0/duplicate/storage/auto_inc_basic.csv b/regression-test/data/data_model_p0/duplicate/storage/auto_inc_basic.csv new file mode 100644 index 0000000000..ab1ffaa522 --- /dev/null +++ b/regression-test/data/data_model_p0/duplicate/storage/auto_inc_basic.csv @@ -0,0 +1,9 @@ +"Bob", 100 +"Alice", 200 +"Tom", 300 +"Test", 400 +"Carter", 500 +"Smith", 600 +"Beata", 700 +"Doris", 800 +"Nereids", 900 \ No newline at end of file diff --git a/regression-test/data/data_model_p0/duplicate/storage/auto_inc_basic_with_null.csv b/regression-test/data/data_model_p0/duplicate/storage/auto_inc_basic_with_null.csv new file mode 100644 index 0000000000..331d6875e1 --- /dev/null +++ b/regression-test/data/data_model_p0/duplicate/storage/auto_inc_basic_with_null.csv @@ -0,0 +1,9 @@ +null, "Bob", 100 +null, "Alice", 200 +null, "Tom", 300 +null, "Test", 400 +4, "Carter", 500 +5, "Smith", 600 +6, "Beata", 700 +7, "Doris", 800 +8, "Nereids", 900 \ No newline at end of file diff --git a/regression-test/data/data_model_p0/duplicate/storage/auto_inc_basic_with_null_2.csv b/regression-test/data/data_model_p0/duplicate/storage/auto_inc_basic_with_null_2.csv new file mode 100644 index 0000000000..53c7494cfb --- /dev/null +++ b/regression-test/data/data_model_p0/duplicate/storage/auto_inc_basic_with_null_2.csv @@ -0,0 +1,9 @@ +10, "Bob", 100 +null, "Alice", 200 +20, "Tom", 300 +null, "Test", 400 +30, "Carter", 500 +null, "Smith", 600 +40, "Beata", 700 +null, "Doris", 800 +50, "Nereids", 900 \ No newline at end of file diff --git a/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_10000.out b/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_10000.out new file mode 100644 index 0000000000..cd251efa81 --- /dev/null +++ b/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_10000.out @@ -0,0 +1,10 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !count_max_min -- +10001 10000 0 + +-- !count_max_min -- +10001 10000 0 + +-- !count_max_min -- +10001 10000 0 + diff --git a/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_basic.out b/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_basic.out new file mode 100644 index 0000000000..a3e4d94187 --- /dev/null +++ b/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_basic.out @@ -0,0 +1,23 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !auto_inc_ids -- +0 "Bob" 100 +1 "Alice" 200 +2 "Tom" 300 +3 "Test" 400 +4 "Carter" 500 +5 "Smith" 600 +6 "Beata" 700 +7 "Doris" 800 +8 "Nereids" 900 + +-- !auto_inc_ids -- +"Bob" 100 0 +"Alice" 200 1 +"Tom" 300 2 +"Test" 400 3 +"Carter" 500 4 +"Smith" 600 5 +"Beata" 700 6 +"Doris" 800 7 +"Nereids" 900 8 + diff --git a/regression-test/data/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.out b/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_col.out similarity index 100% rename from regression-test/data/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.out rename to regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_col.out diff --git a/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_with_null.out b/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_with_null.out new file mode 100644 index 0000000000..ab047f0eba --- /dev/null +++ b/regression-test/data/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_with_null.out @@ -0,0 +1,56 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !auto_inc_ids -- +0 "Bob" 100 +1 "Alice" 200 +2 "Tom" 300 +3 "Test" 400 +4 "Carter" 500 +5 "Smith" 600 +6 "Beata" 700 +7 "Doris" 800 +8 "Nereids" 900 + +-- !auto_inc_ids -- +0 "Alice" 200 +1 "Test" 400 +2 "Smith" 600 +3 "Doris" 800 +10 "Bob" 100 +20 "Tom" 300 +30 "Carter" 500 +40 "Beata" 700 +50 "Nereids" 900 + +-- !auto_inc_ids -- + "Bob" 100 0 + "Alice" 200 1 + "Tom" 300 2 + "Test" 400 3 + "Carter" 500 4 + "Smith" 600 5 + "Beata" 700 6 + "Doris" 800 7 + "Nereids" 900 8 + +-- !auto_inc_ids -- + "Alice" 200 0 + "Test" 400 1 + "Smith" 600 2 + "Doris" 800 3 + "Bob" 100 10 + "Tom" 300 20 + "Carter" 500 30 + "Beata" 700 40 + "Nereids" 900 50 + +-- !sql -- +0 Bob 100 +1 Alice 200 +2 Tom 300 +3 Test 400 +4 Carter 500 +5 Smith 600 +6 Beata 700 +7 Doris 800 +8 Nereids 900 + diff --git a/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_10000.groovy b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_10000.groovy new file mode 100644 index 0000000000..b389ddde50 --- /dev/null +++ b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_10000.groovy @@ -0,0 +1,112 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite("test_dup_table_auto_inc_10000") { + + // auto-increment column is key + def table1 = "test_dup_tab_auto_inc_10000_key" + sql "drop table if exists ${table1}" + sql """ + CREATE TABLE IF NOT EXISTS `${table1}` ( + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID", + `x` int(11) NOT NULL COMMENT "", + `y` int(11) NOT NULL COMMENT "" + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + streamLoad { + table "${table1}" + + set 'column_separator', ',' + set 'format', 'csv' + set 'columns', 'x, y' + + file 'auto_inc_10000.csv' + time 10000 // limit inflight 10s + } + qt_count_max_min "select count(distinct id), max(id), min(id) from ${table1};" + sql "drop table if exists ${table1};" + + // auto-increment column is value + def table2 = "test_dup_tab_auto_inc_10000_value" + sql "drop table if exists ${table2}" + sql """ + CREATE TABLE IF NOT EXISTS `${table2}` ( + `x` int(11) NOT NULL COMMENT "", + `y` int(11) NOT NULL COMMENT "", + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID" + ) ENGINE=OLAP + DUPLICATE KEY(`x`, `y`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`x`, `y`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + streamLoad { + table "${table2}" + + set 'column_separator', ',' + set 'format', 'csv' + set 'columns', 'x, y' + + file 'auto_inc_10000.csv' + time 10000 // limit inflight 10s + } + qt_count_max_min "select count(distinct id), max(id), min(id) from ${table2};" + sql "drop table if exists ${table2};" + + sql "set batch_size = 4096;" + def table3 = "test_dup_tab_auto_inc_10000_key_2" + sql "drop table if exists ${table3}" + sql """ + CREATE TABLE IF NOT EXISTS `${table3}` ( + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID", + `x` int(11) NOT NULL COMMENT "", + `y` int(11) NOT NULL COMMENT "" + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + streamLoad { + table "${table3}" + + set 'column_separator', ',' + set 'format', 'csv' + set 'columns', 'x, y' + + file 'auto_inc_10000.csv' + time 10000 // limit inflight 10s + } + qt_count_max_min "select count(distinct id), max(id), min(id) from ${table3};" + sql "drop table if exists ${table3};" +} \ No newline at end of file diff --git a/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_basic.groovy b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_basic.groovy new file mode 100644 index 0000000000..c5d00658f0 --- /dev/null +++ b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_basic.groovy @@ -0,0 +1,82 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite("test_dup_table_auto_inc_basic") { + + // auto-increment column is key + def table1 = "test_dup_tab_auto_inc_col_basic_key" + sql "drop table if exists ${table1}" + sql """ + CREATE TABLE IF NOT EXISTS `${table1}` ( + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID", + `name` varchar(65533) NOT NULL COMMENT "用户姓名", + `value` int(11) NOT NULL COMMENT "用户得分" + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + streamLoad { + table "${table1}" + + set 'column_separator', ',' + set 'format', 'csv' + set 'columns', 'name, value' + + file 'auto_inc_basic.csv' + time 10000 // limit inflight 10s + } + qt_auto_inc_ids "select * from ${table1};" + sql "drop table if exists ${table1};" + + + // auto-increment column is value + def table2 = "test_dup_tab_auto_inc_col_basic_value" + sql "drop table if exists ${table2}" + sql """ + CREATE TABLE IF NOT EXISTS `${table2}` ( + `name` varchar(65533) NOT NULL COMMENT "用户姓名", + `value` int(11) NOT NULL COMMENT "用户得分", + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID" + ) ENGINE=OLAP + DUPLICATE KEY(`name`, `value`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`name`, `value`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + streamLoad { + table "${table2}" + + set 'column_separator', ',' + set 'format', 'csv' + set 'columns', 'name, value' + + file 'auto_inc_basic.csv' + time 10000 // limit inflight 10s + } + qt_auto_inc_ids "select * from ${table2} order by id;" + sql "drop table if exists ${table2};" +} \ No newline at end of file diff --git a/regression-test/suites/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.groovy b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_col.groovy similarity index 99% rename from regression-test/suites/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.groovy rename to regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_col.groovy index 1a0977dc56..546677b8f1 100644 --- a/regression-test/suites/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.groovy +++ b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_col.groovy @@ -17,7 +17,6 @@ suite("test_dup_table_auto_inc_col") { - // duplicate table with a auto-increment key column def table1 = "test_dup_tab_auto_inc_col1" sql "drop table if exists ${table1}" sql """ diff --git a/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_with_null.groovy b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_with_null.groovy new file mode 100644 index 0000000000..ee62315931 --- /dev/null +++ b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_tab_auto_inc_with_null.groovy @@ -0,0 +1,176 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite("test_dup_table_auto_inc_basic_with_null") { + + // auto-increment column is key, don't specify auto-inc column in stream load + def table1 = "test_dup_table_auto_inc_basic_key_with_null" + sql "drop table if exists ${table1}" + sql """ + CREATE TABLE IF NOT EXISTS `${table1}` ( + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID", + `name` varchar(65533) NOT NULL COMMENT "用户姓名", + `value` int(11) NOT NULL COMMENT "用户得分" + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + streamLoad { + table "${table1}" + + set 'column_separator', ',' + set 'format', 'csv' + set 'columns', 'id, name, value' + + file 'auto_inc_basic_with_null.csv' + time 10000 // limit inflight 10s + } + qt_auto_inc_ids "select * from ${table1};" + sql "drop table if exists ${table1};" + + + // auto-increment column is key, some of the values is null, some is valid value + def table2 = "test_dup_table_auto_inc_basic_key_with_null_2" + sql "drop table if exists ${table2}" + sql """ + CREATE TABLE IF NOT EXISTS `${table2}` ( + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID", + `name` varchar(65533) NOT NULL COMMENT "用户姓名", + `value` int(11) NOT NULL COMMENT "用户得分" + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + streamLoad { + table "${table2}" + + set 'column_separator', ',' + set 'format', 'csv' + set 'columns', 'id, name, value' + + file 'auto_inc_basic_with_null_2.csv' + time 10000 // limit inflight 10s + } + qt_auto_inc_ids "select * from ${table2};" + sql "drop table if exists ${table2};" + + + // auto-increment column is value, don't specify auto-inc column in stream load + def table3 = "test_dup_table_auto_inc_basic_value_with_null" + sql "drop table if exists ${table3}" + sql """ + CREATE TABLE IF NOT EXISTS `${table3}` ( + `name` varchar(65533) NOT NULL COMMENT "用户姓名", + `value` int(11) NOT NULL COMMENT "用户得分", + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID" + ) ENGINE=OLAP + DUPLICATE KEY(`name`, `value`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`name`, `value`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + streamLoad { + table "${table3}" + + set 'column_separator', ',' + set 'format', 'csv' + set 'columns', 'id, name, value' + + file 'auto_inc_basic_with_null.csv' + time 10000 // limit inflight 10s + } + qt_auto_inc_ids "select * from ${table3} order by id;" + sql "drop table if exists ${table3};" + + + // auto-increment column is value, some of the values is null, some is valid value + def table4 = "test_dup_table_auto_inc_basic_value_with_null_2" + sql "drop table if exists ${table4}" + sql """ + CREATE TABLE IF NOT EXISTS `${table4}` ( + `name` varchar(65533) NOT NULL COMMENT "用户姓名", + `value` int(11) NOT NULL COMMENT "用户得分", + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID" + ) ENGINE=OLAP + DUPLICATE KEY(`name`, `value`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`name`, `value`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + streamLoad { + table "${table4}" + + set 'column_separator', ',' + set 'format', 'csv' + set 'columns', 'id, name, value' + + file 'auto_inc_basic_with_null_2.csv' + time 10000 // limit inflight 10s + } + qt_auto_inc_ids "select * from ${table4} order by id;" + sql "drop table if exists ${table4};" + + // insert stmt + def table5 = "test_dup_table_auto_inc_basic_insert_stmt" + sql "drop table if exists ${table5}" + sql """ + CREATE TABLE IF NOT EXISTS `${table5}` ( + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "用户 ID", + `name` varchar(65533) NOT NULL COMMENT "用户姓名", + `value` int(11) NOT NULL COMMENT "用户得分" + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + COMMENT "OLAP" + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2" + ) + """ + sql """insert into ${table5} values + (null, "Bob", 100), + (null, "Alice", 200), + (null, "Tom", 300), + (null, "Test", 400), + (null, "Carter", 500), + (null, "Smith", 600), + (null, "Beata", 700), + (null, "Doris", 800), + (null, "Nereids", 900);""" + qt_sql "select * from ${table5} order by id;" +} \ No newline at end of file diff --git a/regression-test/suites/nereids_syntax_p0/explain.groovy b/regression-test/suites/nereids_syntax_p0/explain.groovy index d0e1ad1fbd..343bf67165 100644 --- a/regression-test/suites/nereids_syntax_p0/explain.groovy +++ b/regression-test/suites/nereids_syntax_p0/explain.groovy @@ -63,7 +63,7 @@ suite("nereids_explain") { when 1>1 then cast(1 as float) else 0.0 end; """ - contains "SlotDescriptor{id=0, col=null, colUniqueId=null, type=double, nullable=false}" + contains "SlotDescriptor{id=0, col=null, colUniqueId=null, type=double, nullable=false, isAutoIncrement=false}" } def explainStr = sql("select sum(if(lo_tax=1,lo_tax,0)) from lineorder where false").toString()